I have two structures declared this way:
struct dot {
int x, y;
};
struct pig : dot {
int z;
};
I can declare dot variable like this:
dot a = {1, 100};
But how can I declare pig variable? The only way I found is this:
pig b;
b.x = 1;
b.y = 100;
b.z = 2134;
Is there any way to do it easier, like with dot variables?
I tried this:
pig b = {1, 100, 2133}
but it doesn't work.
Please, help!
Here's what I was looking for:
struct dot {
int x, y;
};
struct pig : dot {
int z;
pig(int x_, int y_, int z_) : dot{x_, y_}, z{z_} {}
};
pig b{1, 2, 3};
You should always provide the error message your getting. Apart from that: works for me.
Maybe your using an older version of C++. Aggregate initilization was improved in C++17.
don't use
obj = {...}
, useobj{...}
; I got this from a video about C++ features but don't remember where or why exactlyinit lists like that are terrible for knowing which variables got assigned what values, you should use something like
{.x = x, .y = y, .a = a}
(which doesn't compile in this case and that's good)Not sure, why that's directed towards me. I just copied the contents of the OP.
The only semantic difference between the two is: the former (so-called copy initialization) does not allow the usage of constructors declared
explicit
whereas the latter (direct initialization) does. This has let to some inconsistencies in previous versions of the standard (library issue 2193). So the "uniform" initialization can be used more widely. However, the C++ elite is divided on the issue: Bjarne Stroustrup (creator of C++) and Herb Sutter (chairman of the Standard commitee) recommend in their Core Guidelines to use direct initialization as default. Titus Winter and the Google crowd want to the=
by default (source). They find copy initialization has the more natural syntax and that uniformity should not be an end to itself.I don't disagree with that (for non-trivial cases) but we have the same problem with function and template parameters for which C++20 doesn't provide an equivalent solution – other than wrapping everything in a single object or tag types, respectively.
I just put my thoughts into some replies 11 but for function/template arguments, you at least don't have inheritance so there are no questions about "is z the first or last value in the init list?" for sure. I use
f(/*name=*/value)
for function parameters that need naming, or you can have IDE help you with that.Here's a question for you to think about: what sort of instructions does the syntax of "derived class" correspond to? Keep in mind that a struct is a class and gets default constructors if you don't specify any.
You insert an implicit
super()
at the start of your derived class constructor. In this case, since you didn't specify explicit constructors, thesuper()
call isdot()
and the called constructor ofpig
isInit lists complicate the hell out of that, but you can see that you use things in a way you didn't set up. Instead:
(at least I think you can put
dot{x_, y_}
anda{a_}
together here)Lesson: don't use implicit constructors for non-trivial classes.
thanks for explanation!
pig b = { { 1, 100 }, 2133 };
?No, it doesn't compile. This implementation works:
Please tell me where you compile and what error is.
AFAIK, my way must work since C++17.
Experiment was success on local MSVC++ 2019, wandbox gcc 12 and wandbox clang 13.
clang
gcc
You are right. It didn't compile because i used C++14. If you use C++17, everything is ok and your method works.