【问题标题】:Calling constructor with braces instead parantheses用大括号而不是括号调用构造函数
【发布时间】:2015-06-29 09:10:45
【问题描述】:

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

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

这个语法正确吗?似乎是,虽然我希望在调用函数时总是使用括号,比如Foo({42})。在clang++和g++中compiles fine下面的示例代码

#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})
}

所以,总而言之,我的问题如下:在委派构造函数时是否有特殊规则,允许仅使用大括号调用初始化列表构造函数,例如Foo{something}

【问题讨论】:

  • 你问的最有趣的问题

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


【解决方案1】:

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

此外,标准规定([class.base.init]/7 in C++14)expression-listbraced-init-list em> 根据通常的初始化规则发生。因此,如果初始值设定项是 braced-init-list,那么 std::initializer_list 构造函数将在重载决议中受到青睐。

【讨论】:

    【解决方案2】:

    我认为规则很明确,您可以委托给初始化列表构造函数(强调我的):

    如果类本身的名称在 成员初始值设定项列表,则该列表必须由该成员组成 仅初始化器;这样的构造函数被称为委托 构造函数,以及由唯一成员选择的构造函数 初始化器列表是目标构造函数在这种情况下,目标 构造函数由重载决议选择并首先执行, 然后控件返回委托构造函数,其主体为 执行。

    因此,通过重载决议,您可以调用初始化列表构造函数,就像在“正常”代码中调用它一样,因为。

    但是,我不知道任何应该允许调用接受初始化列表的函数的方法,就像调用构造函数一样。

    编辑:More 关于构造函数规则(再次强调我的):

    任何构造函数的函数定义的主体,在 复合语句的左大括号,可以包括 成员 初始化列表,其语法为冒号:,后跟 一个或多个成员初始化器的逗号分隔列表,每个 它具有以下语法
    类或标识符(表达式列表(可选))(1)
    类或标识符大括号初始化列表 (2) (C++11 起)
    参数包 ... (3) (C++11 起)

    1) 使用类或标识符初始化基类或成员 直接初始化,或者,如果表达式列表为空, 值初始化
    2) 初始化由 使用列表初始化的类或标识符(变为 如果列表为空,则进行值初始化和聚合初始化 初始化聚合时)
    3) 使用 a 初始化多个碱基 包扩展

    所以根据#2,它似乎是合法的。

    【讨论】:

    • 我明白这一点,我知道我可以委托给一个初始化列表,但不知道我也可以像 Foo{...} 一样调用它,而不一定是 Foo({...})
    猜你喜欢
    • 2013-03-02
    • 2013-01-17
    • 2015-09-25
    • 1970-01-01
    • 2020-05-28
    • 1970-01-01
    • 2012-07-06
    • 1970-01-01
    • 2018-05-14
    相关资源
    最近更新 更多