Why C++11 in-class initializer cannot use parentheses?(为什么 C++11 类内初始化器不能使用括号?)
问题描述
例如,我不能这样写:
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++ 程序员感到惊讶和不直观的事情.添加新的 brace-or-equal-initializer 语法是避免这种歧义并从头开始的机会,这可能是 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
的构造函数,那么当该类型的构造函数总是被首先考虑是一个 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 类内初始化器不能使用括号?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:为什么 C++11 类内初始化器不能使用括号?
基础教程推荐
- 管理共享内存应该分配多少内存?(助推) 2022-12-07
- 如何“在 Finder 中显示"或“在资源管理器中显 2021-01-01
- 为什么语句不能出现在命名空间范围内? 2021-01-01
- 从 std::cin 读取密码 2021-01-01
- 在 C++ 中循环遍历所有 Lua 全局变量 2021-01-01
- 如何使图像调整大小以在 Qt 中缩放? 2021-01-01
- 为 C/C++ 中的项目的 makefile 生成依赖项 2022-01-01
- 使用从字符串中提取的参数调用函数 2022-01-01
- 如何在不破坏 vtbl 的情况下做相当于 memset(this, ...) 的操作? 2022-01-01
- Windows Media Foundation 录制音频 2021-01-01