使用大括号调用构造函数而不是parantheses

vso*_*tco 1 c++ constructor initializer-list c++11 delegating-constructor

我最近意识到在C++ 11中我们可以调用委托初始化列表构造函数

Foo() : Foo{42} // delegate to Foo(initializer_list<>)
Run Code Online (Sandbox Code Playgroud)

这种语法是否正确?它似乎是,虽然我希望在调用函数时总是使用括号,比如Foo({42}).下面的示例代码在clang ++和g ++ 中编译都很好

#include <iostream>
#include <initializer_list>

struct Foo
{
    Foo() : Foo{42} // I would have expected invalid syntax, use Foo({42})
    {
        std::cout << "Foo()... delegating constructor\n";
    }
    Foo(std::initializer_list<int>)
    {
        std::cout << "Foo(initializer_list)\n";
    }
};

int main()
{
    Foo foo;
}
Run Code Online (Sandbox Code Playgroud)

我很清楚统一初始化,比如使用声明对象{ },但不知道我们也可以调用构造函数.我们不能调用函数,以下不编译:

#include <initializer_list>

void f(std::initializer_list<int>){}

int main()
{
    f{5}; // compile time error, must use f({5})
}
Run Code Online (Sandbox Code Playgroud)

总而言之,我的问题如下:委托构造函数时是否有特殊规则,允许仅使用大括号调用init-list构造函数,如Foo{something}

Bri*_*ian 5

是的,mem-initializerFoo{42}可以包含带括号的表达式列表或带括号的init-list.无论mem-initializer-id是表示构造函数的类,基类还是成员,都是这种情况:也就是说,无论是构造函数委托还是不委托.请参阅[class.base.init]中的语法.

此外,该标准指定(C++ 14中的[class.base.init]/7)表达式列表braced-init-list的初始化根据通常的初始化规则发生.因此,如果初始化程序是braced-init-list,那么std::initializer_list构造函数将在重载解析中受到青睐.