为什么C ++ 11类的初始化器不能使用括号? [英] Why C++11 in-class initializer cannot use parentheses?
问题描述
例如,我不能写这个:
class A
{
vector<int> v(12, 1);
};
我只能写这个:
class A
{
vector<int> v1{ 12, 1 };
vector<int> v2 = vector<int>(12, 1);
};
C ++ 11语言设计的差异是什么考虑因素?
What's the consideration for the differences in C++11 language design?
推荐答案
一个可能的原因是,允许括号会使我们回到最烦躁的解析。考虑下面两种类型:
One possible reason is that allowing parentheses would lead us back to the most vexing parse in no time. Consider the two types below:
struct foo {};
struct bar
{
bar(foo const&) {}
};
现在,您有一个 bar
您要初始化,因此您将其定义为
Now, you have a data member of type bar
that you want to initialize, so you define it as
struct A
{
bar B(foo());
};
但是你在上面做的是声明一个名为 B
,它返回一个
bar
对象的值,并且接受一个具有签名 foo()
(返回 foo
,不带任何参数)。
But what you've done above is declare a function named B
that returns a bar
object by value, and takes a single argument that's a function having the signature foo()
(returns a foo
and doesn't take any arguments).
的问题在StackOverflow处理这个问题,这是大多数C ++程序员发现令人惊讶和不直观的东西。添加新的大括号或等号初始化语法是避免这种歧义的一个机会,并从一个干净的slate开始,这可能是C ++委员会选择这样做的原因。
Judging by the number and frequency of questions asked on StackOverflow that deal with this issue, this is something most C++ programmers find surprising and unintuitive. Adding the new brace-or-equal-initializer syntax was a chance to avoid this ambiguity and start with a clean slate, which is likely the reason the C++ committee chose to do so.
bar B{foo{}};
bar B = foo();
上面两行都声明一个名为 B
bar
。
Both lines above declare an object named B
of type bar
, as expected.
除了猜测外上面的例子中,我想指出,你在上面的例子中做了两个截然不同的事情。
Aside from the guesswork above, I'd like to point out that you're doing two vastly different things in your example above.
vector<int> v1{ 12, 1 };
vector<int> v2 = vector<int>(12, 1);
第一行将 v1
初始化为向量包含两个元素 12
和 1
。第二个创建一个包含 12
元素的向量 v2
,每个元素初始化为 1
。
The first line initializes v1
to a vector that contains two elements, 12
and 1
. The second creates a vector v2
that contains 12
elements, each initialized to 1
.
注意这个规则 - 如果一个类型定义了一个构造函数,它接受 initializer_list< T>
当类型的初始化器是 braced-init-list 时,始终被认为是构造函数。其他构造函数只有当 initializer_list
不可行时才会考虑。
Be careful of this rule - if a type defines a constructor that takes an initializer_list<T>
, then that constructor is always considered first when the initializer for the type is a braced-init-list. The other constructors will be considered only if the one taking the initializer_list
is not viable.
这篇关于为什么C ++ 11类的初始化器不能使用括号?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!