4

代码:

class A {
  std::vector<int> x = {2,3};                 // x[0] = 2 and x[1] = 3
  std::vector<int> y = std::vector<int>(2,3); // x[0] = 3 and x[1] = 3 Too verbose!!  
};

有没有一种方法可以调用std::vector<int>仅使用大括号初始化程序的构造函数,或者至少使用较短的版本来产生相同的效果?

我不想重复std::vector<int>

4

2 回答 2

6

有什么我可以使用的黑客吗?

如果您的唯一目标是不必“明确”指定类型两次,您可以使用它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以获得确认但可能不是那么明显的解决方案。

于 2012-07-11T17:54:02.947 回答
-2

梦幻般的解决方案..

如果你只是不想重复std::vector,怎么样

class A
{
    auto y = std::vector<int>(2,3);
};

是不允许的,标准说(7.1.6.4)[dcl.spec.auto]

类型说明auto符还可用于在选择语句或迭代语句的条件中、在新表达式的新类型标识类型标识中的类型说明符序列中、在for-range-declaration,以及使用出现在类定义的成员规范中的大括号或等号初始化器声明静态数据成员

当将大括号或相等初始化器语法添加到非静态成员时,他们可能忘记更新这一行。

于 2012-07-11T17:51:49.500 回答