本文介绍了用大括号而不是括号调用构造函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I recently realized that in C++11 we can call a delegating initializer-list constructor like

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

此语法正确吗?尽管我希望在调用函数时总是使用括号,例如 Foo({42})

Is this syntax correct? It seems to be, although I would have expected to always use parentheses when calling a function, like Foo({42}). The example code below compiles fine in both clang++ and 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;
}

我很清楚统一初始化,例如声明对象使用 {} ,但不知道我们也可以调用构造函数。但是,我们无法调用函数,以下:

I am well aware of uniform initialization, like declaring objects using { }, but did not know we can also call constructors. We cannot call functions though, the following doesn't compile:

#include <initializer_list>

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

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

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

So, to summarize, my question is the following: are there special rules when delegating constructors, that allow for calling a init-list constructor using only braces, like Foo{something}?

推荐答案

是的,内存初始化器,例如 Foo {42} 可以包含带括号的 expression-list braised-init-list 。不管 mem-initializer-id 是表示构造函数的类,基类还是成员,都属于这种情况:也就是说,无论构造函数是委托还是不委托。参见[class.base.init]中的语法。

Yes, a mem-initializer such as Foo{42} can contain either a parenthesized expression-list or a braced-init-list. This is the case regardless of whether the mem-initializer-id denotes the constructor's class, a base class, or a member: that is, both when the constructor delegates and when it does not. See the grammar in [class.base.init].

此外,该标准还规定(在C ++ 14中为[class.base.init] / 7)由 expression-list braced-init-list 进行的初始化根据通常的初始化规则进行。因此,如果初始化程序是 braised-init-list ,则 std :: initializer_list 构造函数将在重载解析中得到支持。

Furthermore, the standard specifies ([class.base.init]/7 in C++14) that the initialization by the expression-list or braced-init-list occurs according to the usual rules of initialization. Therefore if the initializer is a braced-init-list then std::initializer_list constructors will be favoured in overload resolution.

这篇关于用大括号而不是括号调用构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-18 13:40