在C ++ 11(或将来)中,是否有以下简单的变体是合法的?
class A
{
public:
std::vector<char> b(123); // declare a vector with 123 elements
};
我能找到的最近的是有点笨重,也许效率低下......
class A
{
public:
std::vector<char> b = std::vector<char>(123);
};
我正在尝试避免使用初始化列表。我更喜欢将b
的声明和初始化合并到一行代码中。矢量将始终具有相同的大小。
我在这个例子中使用std::vector
,但可能更普遍适用答案。
为了更好地衡量,这是来自gcc
版本4.8的错误消息:
错误:数字常量之前的预期标识符 std :: vector b(123);
这是来自clang
版本3.7的消息:
错误:预期的参数声明符 std :: vector b(123);
答案 0 :(得分:6)
极不可能。最初允许NSDMI的提案解决了这个问题:
Kona就标识符范围提出了一个问题:
在2007年9月的核心工作组讨论期间 在科纳举行会议时,出现了一个关于标识符范围的问题 初始化器。我们是否希望允许类范围 正向查找;或者我们是否要求初始化者 在他们被解析的时候明确定义了吗?
想要的是什么:
类范围查找的动机是我们希望能够 把任何东西都放在我们可以的非静态数据成员的初始化器中 放入mem-initializer而不会显着改变语义 (模数直接初始化与复制初始化):
int x(); struct S { int i; S() : i(x()) {} // currently well-formed, uses S::x() // ... static int x(); }; struct T { int i = x(); // should use T::x(), ::x() would be a surprise // ... static int x(); };
问题1:
不幸的是,这会使“( 表达式列表 )”的初始化程序 在解析声明时表单不明确:
... 的
提案:
CWG在Kona进行了6比3的民意调查,支持分类范围查询; 这就是本文提出的,非静态的初始化器 数据成员仅限于“ = 初始化条款”和“ { 初始化列表 } “表单。我们相信:
问题1 :由于我们不建议(),因此不会出现此问题 符号。 = 和 {} 初始值表示法不会受此影响 问题
除非你的编译器不使用复制省略(并且所有主要的复制省略),否则关于笨重的初始化方式没有任何低效率。问题是C ++的语言设计者已经将自己置于一个角落。因为初始化列表构造函数是 greedy ,所以大括号初始化将构造具有给定元素的向量,而使用括号的较旧语法调用显式构造函数来设置大小。
除非您无法在NSDMI中使用该构造函数。除非你使用等号。
如果由于某种原因困扰你,有一些笨重的解决方法:
std::vector<char> c = decltype(c)(123);
// ...
using VChar = std::vector<char>;
VChar v = VChar(123);
或者意识到新功能并不排除现有功能:
std::vector<char> c;
A() : c(123)
{
}