Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ structs: force initialize members? [duplicate]

Tags:

c++

c++20

e.g.

#include <iostream>
using namespace std;


struct Point {
    int x;
    int y;
};

int main() {
    Point p1 {1};
    Point p2 {.y=2};

    cout << p1.x << ", " << p1.y << endl;
    cout << p2.x << ", " << p2.y << endl;
    return 0;
}

https://ideone.com/DlJRfU

Is there any way to force the caller to initialize all struct members when using initializer lists? I want to ensure both x and y are set by the caller in this example.

I also want to allow designated initializers. Many of our structs are very long and that syntax adds much-needed clarity.

like image 419
mpen Avatar asked Jul 22 '26 09:07

mpen


2 Answers

Something like what you want is possible in practice by making the aggregate meaninglessly templated:

template<class Bad>
struct PointImpl {
  int x=Bad(),y=Bad();
};
using Point=PointImpl<void>;

void f() {
  Point p0;             // error
  Point p1{1};          // error
  Point p2{.y=2};       // error
  Point p3{.x=1};       // error
  Point p4{.x=1,.y=2};  // OK
}

I won’t say I morally agree with this sort of “defeat the client” approach, and it’s not even clear from the standard that default member initializers should work like default arguments this way ([temp.inst]/3, /11, and /13 don’t mention them at all), but implementations agree that they do.

like image 131
Davis Herring Avatar answered Jul 25 '26 01:07

Davis Herring


You could add a 2-parameter constructor. That would force initializing with both parameters.

Point(int x, int y) : x(x), y(y) {}
Point() = default; // to maintain behaviour of default constructor

then

Point p1{1, 2}; // OK
Point p1 {1}; // error: no matching constructor for initialization of 'Point'
Point p2 {.y=2}; // error: no matching constructor for initialization of 'Point'

Note that this means Point is no longer an aggregate, which means you can no longer use designated initializers.

like image 34
juanchopanza Avatar answered Jul 25 '26 02:07

juanchopanza