为什么C ++ 11类的初始化器不能使用括号? [英] Why C++11 in-class initializer cannot use parentheses?

查看:195
本文介绍了为什么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 ++程序员发现令人惊讶和不直观的东西。添加新的大括号或等号初始化语法是避免这种歧义的一个机会,并从一个干净的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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆