有什么我可以使用的黑客吗?
如果您的唯一目标是不必“明确”指定类型两次,您可以使用它decltype
来为您的任务提供一些帮助:
class Obj {
std::vector<int> v1 = decltype(v1) (2,3);
};
还要记住typedef
/using
是不必输入1的好方法:
struct Obj {
using VInt = std::vector<int>;
// typedef std::vector<int> VInt;
VInt v = VInt (3,2);
};
1. 双关语不是故意的
标准对此有何评论?
可悲的是,该标准对在您的班级主体中初始化成员进行了以下说明:
9.2/5 类成员 [class.mem]
可以使用大括号或相等初始化器来初始化成员。(对于静态数据成员,见 9.4.2;对于非静态数据成员,见 12.6.2)。
我们已经发现了一些关于在初始化成员时可以做什么和不可以做什么的提示,但是为了 100% 确定我们应该继续阅读大括号或等式初始化器的真正含义。
8.5/1 初始化程序 [dcl.init]
...
大括号或相等初始化器:
=初始化子句
花括号初始化列表
初始化子句:
赋值表达式
大括号初始化列表
初始化器列表:
初始化器子句 ...opt
初始化器列表,初始化器子句 ...opt
支撑初始化列表:
{初始化列表 ,选择}
{ }
通过上面的括号或相等初始化器规范,我们发现在初始化类体内的成员时面临两个选择,要么使用 a=
和初始化器子句,要么单独使用 a braced-init-list
。
以上归结为以下两者之一:
struct Obj {
Type foo = Type (1,2,3); /* example of an initializer-clause */
Type bar {1,2,3}; /* example of a braced-init-list */
};
支撑初始化列表看起来很棒,让我们使用它!
由于std::vector<...>
接受std::initializer_list
它的构造函数的一个重载,我们不能使用花括号初始化列表来调用带有两个参数的构造函数(size_type count, const T& value)
,因为这将被用作我们的向量的内容。
因此,我们坚持使用初始化子句。
请参阅前面的hack以获得确认但可能不是那么明显的解决方案。