Is it possible to prevent omission of aggregate initialization members?

前端 未结 5 1936
孤城傲影
孤城傲影 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:59

    Not an elegant and handy solution, I suppose... but should works also with C++11 and give a compile-time (not link-time) error.

    The idea is to add in your struct an additional member, in the last position, of a type without default initialization (and that cannot initialize with a value of type VariablePtr (or whatever is the type of preceding values)

    By example

    struct bar
     {
       bar () = delete;
    
       template  
       bar (T const &) = delete;
    
       bar (int) 
        { }
     };
    
    struct foo
     {
       char a;
       char b;
       char c;
    
       bar sentinel;
     };
    

    This way you're forced to add all elements in your aggregate initialization list, included the value to explicit initialize the last value (an integer for sentinel, in the example) or you get a "call to deleted constructor of 'bar'" error.

    So

    foo f1 {'a', 'b', 'c', 1};
    

    compile and

    foo f2 {'a', 'b'};  // ERROR
    

    doesn't.

    Unfortunately also

    foo f3 {'a', 'b', 'c'};  // ERROR
    

    doesn't compile.

    -- EDIT --

    As pointed by MSalters (thanks) there is a defect (another defect) in my original example: a bar value could be initialized with a char value (that is convertible to int), so works the following initialization

    foo f4 {'a', 'b', 'c', 'd'};
    

    and this can be highly confusing.

    To avoid this problem, I've added the following deleted template constructor

     template  
     bar (T const &) = delete;
    

    so the preceding f4 declaration gives a compilation error because the d value is intercepted by the template constructor that is deleted

提交回复
热议问题