Reputation: 4024
I have this class X
, using delegating constructor I want to change only the value i
and j
as 0. Is it possible to do so?
class X{
public:
X() = default;
X(int ival, int jval) : i{ ival }, j{ jval } {}
X(int new_i) : i{ new_i }, X(i, 0) {} //error here
private:
int i;
int j;
};
int main()
{
X x{ 345, 54 };
x = X{ 34 }; //annoymous copy changes only the i:member
return 0;
}
EDIT: I know X(int new_int) : X{new_int, 0}
will work but i wanted to know what's the error if initialise one more variable in the list.
May be I have another z
and I want to initialise that along with i
and j
.
i.e. X(int new_i) :z{ new_i }, X(new_i, 0) {}
Upvotes: 2
Views: 83
Reputation: 45444
You cannot have a delegating constructor and another member-initialiser in the initialiser list. That's not allowed, because the order of initialisation cannot possibly be the order of member declaration, instead some variables will be initialised twice, which is potentially ill-defined.
If your example were allowed, then the constructor in question would first initialise i
<-new_i
, then i
<--i
, then j
<--0
. With non-const
int
, this may be feasable, but not with more general types.
Simply initialise the objects via the delegation:
class X
{
public:
X() = default;
X(int ival, int jval) : i{ival}, j{jval} {}
X(int ival) : X(ival, 0) {}
private:
int i;
int j;
};
Though in this case, it's better to use default arguments:
class X
{
public:
X() = default;
X(int ival, int jval=0) : i{ival}, j{jval} {}
private:
int i;
int j;
};
You should also consider to use the explicit
keyword for single-argument constructors to avoid unpleasant surprises ... as in
void foo(X);
foo(1); // calls foo(X(1));
Upvotes: 1
Reputation: 206607
Just use
X(int new_i) : X(new_i, 0) {}
From the C++ Draft Standard N3337 (emphasis mine):
12.6.2 Initializing bases and members
6 A
mem-initializer-list
can delegate to another constructor of the constructor’s class using anyclass-or-decltype
that denotes the constructor’s class itself. If amem-initializer-id
designates the constructor’s class, it shall be the onlymem-initializer
;
Upvotes: 2
Reputation: 56557
Why don't you do this?
X(int new_i) :X(new_i, 0){...}
In this way, you will set j
-th value to 0, and have only x
variable.
Upvotes: 1