问题描述
我最近意识到,在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.
这篇关于用大括号而不是括号调用构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!