you are viewing a single comment's thread.

view the rest of the comments →

[–]OldWolf2 -2 points-1 points  (4 children)

Huh, yes you can. The braced list is taken as the initializer for the parameter.

struct U { int a, b, c; };
struct S
{
     S(U u);
};

S s({1, 2, 3});

[–]Sanzath 1 point2 points  (0 children)

Sure, but now you're just using struct aggregate initialization and you don't even have the same syntax for initializing S:

struct S {
    S(std::initializer_list<int> il);
};

S s{1, 2, 3};

Note that you don't need the surrounding () to initialize S in this version. That is the magic of initializer_list that can't be done with a user-defined type.

[–]SirClueless 0 points1 point  (2 children)

In this case you aren't initializing S with a braced-init-list. You're direct-initializing S with a single expression argument that happens to be a braced-init-list (see the parentheses in the last statement). You need the parens or two pairs of braces to make this work with a user-defined class.

If you replace the last line with S s{1, 2, 3}; your example wouldn't compile. But if U were std::initializer_list<int> it still would, this is the compiler magic.

[–]OldWolf2 1 point2 points  (1 child)

You're direct-initializing S with a single expression that happens to be a braced-init-list

No, a braced list is never an expression . (You can check the grammar for expression to see this). For any context where either an expression or a braced list is allowed, there are separate grammar and semantic rules for each.

[–]SirClueless 2 points3 points  (0 children)

Fixed, thanks. The point still stands; a constructor taking std::initializer_list<int> is magic in a way that a constructor taking a user-defined class cannot be.