c++ - 使用大括号而不是圆括号调用构造函数

标签 c++ c++11 constructor initializer-list delegating-constructor

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

Foo() : Foo{42} // delegate to Foo(initializer_list<>)

这个语法正确吗?似乎是这样,尽管我希望在调用函数时始终使用圆括号,例如 Foo({42})。下面的示例代码 compiles fine在 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;
}

我很清楚统一初始化,比如使用 { } 声明对象,但不知道我们也可以调用构造函数。但是我们不能调用函数,下面的doesn't compile :

#include <initializer_list>

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

int main()
{
    f{5}; // compile time error, must use f({5})
}

因此,总而言之,我的问题如下:委托(delegate)构造函数时是否有特殊规则,允许仅使用大括号调用初始化列表构造函数,如 Foo{something}

最佳答案

是的,mem-initializer 例如 Foo{42}可以包含带括号的 expression-listbraced-init-list。无论 mem-initializer-id 表示构造函数的类、基类还是成员,情况都是如此:也就是说,无论是在构造函数委托(delegate)时还是在不委托(delegate)时。参见[class.base.init]中的语法。

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

关于c++ - 使用大括号而不是圆括号调用构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29785223/

相关文章:

c++ - 在 NT4 上 boost MFC 应用程序

c++ - 什么时候在构造函数中调用虚函数是安全的

c++ - 如何将 RSA 公钥和私钥读入单个 RSA 结构?

c++ - (Qt 5.4.1)此应用程序无法启动,因为它找不到或加载Qt平台插件 "xcb"

c++ - C++11 中的 std::forward_list swap() 实现

c++ - 使用不同的 C++ 环境创建 DLL

c++11 - 为什么 std::aligned_union 需要最小尺寸作为模板参数?

c++ - 初始化列表是否总是在构造函数代码之前处理?

java - 将异常消息传递给父类,而不使用 throw new exception(); 构造​​ , 消息;

C++ 编译时间特定函数与可变参数模板