Recently I asked this question but now I would like to expand it. I wrote the following class:
template
class X{
public:
vector v;
First, your code doesn't compile for me.
main.cpp:7:15: error: declaration of ‘class T’
template
^
main.cpp:3:11: error: shadows template parm ‘class T’
template
^
I changed the outer one to U
.
template
class X{
public:
vector v;
template
X(T n) {
v.push_back(n);
}
template
X(T n, T2... rest) {
v.push_back(n);
X(rest...);
}
};
You're correct that this causes the issue you gave in the question details...
X obj(1, 2, 3); // obj.v containts only 1
This is because the statement X(rest...)
at the end of your constructor doesn't recursively call the constructor to continue initializing the same object; it creates a new X
object and then throws it away. Once a constructor's body begins to execute, it's no longer possible to invoke another constructor on the same object. Delegation must occur in the ctor-initializer. So for example, you could do this:
template
X(T n, T2... rest): X(rest...) {
v.insert(v.begin(), n);
}
That sucks though, because inserting at the beginning of a vector isn't efficient.
Better to take a std::initializer_list
argument. This is what std::vector
itself does.
X(std::initializer_list il): v(il) {}
// ...
X obj {1, 2, 3};