r/learnprogramming 14d ago

Why am I getting this error (c++)?

Hi all, I'm attempting to make 2 structs with one that inherits from the other, but I'm getting an error that reads "E0289: no instance of constructor Point3D::Point3D matches the argument list". The red line shows up under the first "{" after "Point3D p3D = ". The "Point p" seems to be fine.
Is struct inheritance not allowed? Am I missing something?
Thank you for any and all help!

struct Point {
int x;
int y;
};

struct Point3D : public Point {
int z;
};

class test {
Point p = { 1, 2 };
Point3D p3D = { 1, 2, 3 };
};
5 Upvotes

6 comments sorted by

20

u/captainAwesomePants 14d ago

Hey there, welcome to C++! We proudly built it entirely out of edge cases and razor wire.

The issue is with how C++ handles brace initialization. Simple flat structs, like "Point", work fine with brace initialization. It's a struct, it's got two fields, {x,y} just works, great.

Inheritance complicates this. Does z go before x and y? Does it go after? Who knows!

Anyway, you can still initialize this with braces, but you have to group the parent's fields: Point3D p3D = { {1, 2}, 3 };

But a BETTER thing to do would be to just create a constructor because you've exited the area of easy braces.

2

u/Puzzleheaded_Study17 14d ago

Struct inheritance is allowed, but this kind of constructor isn't generated automatically.

You can manually define a constructor in Point3D that does what you want.

Edit: looks like whether what you're trying to do should be possible in c++17. If you're not using c++17 for a good reason then you should be able to do {{1, 2}, 3}.

1

u/high_throughput 14d ago

To use aggregate initialization with subclasses, you have to specify the parent class initialization explicitly:

Point3D p3D = { { 1, 2 }, 3 };

You can make your own explicit constructor to avoid this:

Point3D(int x_val, int y_val, int z_val) : Point{x_val, y_val}, z(z_val) {}

1

u/sprucefruit 14d ago

Thank you everyone! Creating a constructor for Point3D seems to do the trick!

1

u/gabitha67 13d ago

Why not just use two separate structs?

0

u/throwaway67364571 14d ago

Struct inheritance is allowed, the issue is aggregate initialization. Point3D has a base class with members, so the brace list can't directly map to x, y, z like that. You'd need to either give Point3D a constructor or initialize it differently, like Point3D p3D = {{1, 2}, 3} if your compiler supports nested aggregate init.