Is it possible to prevent omission of aggregate initialization members?

前端 未结 5 1945
孤城傲影
孤城傲影 2021-02-05 00:24

I have a struct with many members of the same type, like this

struct VariablePointers {
   VariablePtr active;
   VariablePtr wasactive;
   VariablePtr filename;         


        
5条回答
  •  春和景丽
    2021-02-05 00:43

    The simplest way is not to give the type of the members a no-arg constructor:

    struct B
    {
        B(int x) {}
    };
    struct A
    {
        B a;
        B b;
        B c;
    };
    
    int main() {
    
            // A a1{ 1, 2 }; // will not compile 
            A a1{ 1, 2, 3 }; // will compile 
    

    Another option: If your members are const & , you have to initialize all of them:

    struct A {    const int& x;    const int& y;    const int& z; };
    
    int main() {
    
    //A a1{ 1,2 };  // will not compile 
    A a2{ 1,2, 3 }; // compiles OK
    

    If you can live with one dummy const & member, you can combine that with @max66's idea of a sentinel.

    struct end_of_init_list {};
    
    struct A {
        int x;
        int y;
        int z;
        const end_of_init_list& dummy;
    };
    
        int main() {
    
        //A a1{ 1,2 };  // will not compile
        //A a2{ 1,2, 3 }; // will not compile
        A a3{ 1,2, 3,end_of_init_list() }; // will compile
    

    From cppreference https://en.cppreference.com/w/cpp/language/aggregate_initialization

    If the number of initializer clauses is less than the number of members or initializer list is completely empty, the remaining members are value-initialized. If a member of a reference type is one of these remaining members, the program is ill-formed.

    Another option is to take max66's sentinel idea and add some syntactic sugar for readability

    struct init_list_guard
    {
        struct ender {
    
        } static const end;
        init_list_guard() = delete;
    
        init_list_guard(ender e){ }
    };
    
    struct A
    {
        char a;
        char b;
        char c;
    
        init_list_guard guard;
    };
    
    int main() {
       // A a1{ 1, 2 }; // will not compile 
       // A a2{ 1, init_list_guard::end }; // will not compile 
       A a3{ 1,2,3,init_list_guard::end }; // compiles OK
    

提交回复
热议问题