c++11language-lawyeraggregate-initialization

C++11 Aggregate initialization of private member, is it correct?


Is it correct to initialize private member through aggregate initialization while passing it as a parameter into owner's class function? Just look at code below.

class A {
  struct S {
    int t, u;
  };
public:
  void f(const S& s) {}  
};

int main() {
  A a;
  a.f({1, 2}); // correct?
  return 0;
}

I checked standard and nets and it seems that there is no exact answer. Looks like mechanics are as follows: * braced initializer is public thing and thus user doesn't violate access restrictions. * implicit conversion from initializer into "S" is internal for "S" and thus also fine for compiler.

The question is, whether there is some reference in standard, draft or at least cppreference with the description of this behaviour?


Solution

  • Yes this is correct. The only thing private about S is the name. Access control only controls access through the name ([class.access]p4). So you could use a type trait to get the type of S for example through f's type (example).

    So, it is allowed because there is no restriction [dcl.init.agg] that prohibits initializing "private" types.

    There is also a note in C++ draft, found by @Stepan Dyatkovskiy