'CRTP variable inizializatin in derived class
Consider the following code implementing CRTP
#include <iostream>
template <typename T>
class base {
int n;
base() {}
friend T;
public:
explicit base(int _n) : n{_n} {}
void print() const { static_cast<const T&>(*this).whoami(); }
};
class derived : public base<derived> {
public:
void whoami() const { std::cout << n << std::endl; }
};
int main()
{
base<derived> a{6};
a.print();
}
The code prints 6 as expected.
The default constructor base::base() would leave the member field n uninitialized. However, since it is private and base is friend to derived, only derived uses base::base() (specifically, in its compiler-generated default contructor). But derived has not public constructors, so it is never instantiated. So the code seems to be safe from the point of the initialization of n, though there is a part of the code that, effectively, does not perform the correct initialization.
So I wonder: is there a pitfall in a code like above?
Note
Please notice that the question it not merely academic. In a real-world case, the members of base may not have a sensible default initialization, and are initialized by a constructor of base that takes a series of parameters. These parameters can be possibly determined at runtime only, and used in main() to instantiate base<derived>.
class base {
public:
base(int param1, char *param2);
};
If there is no default constructor for base, you need a constructor for derived that calls the constructor of the base class base<derived>. When this has no sensible default parameters, it would be very awkward to call it with
"random" parameters
class derived : public base<derived> {
derived() : base<derived>(42, "unexisting_file") { }
};
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
