繁体   English   中英

const&向量成员在ctor中用const&向量初始化

[英]const& vector member initialized with const& vector in ctor

我有以下代码,其中有成员v_ ,即对int向量的const引用。 它使用左值初始化,所以我的想法是这不会引起任何复制。

#include <iostream>
#include <iterator>
#include <vector>

using Vec = std::vector<int>;

void out(Vec const& v) {
  using namespace std;
  cout << "Vector (" << &v[0] << "): [";
  ostream_iterator<int> out_it (cout,", ");
  copy(v.begin(), v.end(), out_it);
  cout << "]\n";
}

struct V {
  V(Vec const& v) : v_{v}{}
  Vec const& v_;
};

int main(int argc, char** argv) {
  Vec v = { 1, 2, 3, 4, 5 };
  out(v);
  V wrapped { v };
  out(wrapped.v_);
}

使用clang版本3.6.0(trunk 225298),我得到以下输出:

~/tmp$ clang++ -std=c++11 -g -O0 vecmember.cpp
~/tmp$ ./a.out
Vector (0x2480010): [1, 2, 3, 4, 5, ]
Vector (0x2480010): [1, 2, 3, 4, 5, ]

这就是我所希望的。 但是,使用c ++(Ubuntu 4.8.2-19ubuntu1)4.8.2,我得到以下输出:

~/tmp$ c++ -std=c++11 -g -O0 vecmember.cpp
~/tmp$ ./a.out
Vector (0xa58010): [1, 2, 3, 4, 5, ]
Vector (0xa58030): []

当我进入调试器时,它将进入stl_vector.h函数vector(const vector&__x),因此它试图复制构造传递给构造函数的原始向量。 这是编译器错误,还是我以某种方式做了未定义的错误或只是完全错误?

无论哪种情况,哪种方法更好?

C ++ 11标准实际上表示,当您像这样对引用进行列表初始化时:

int i;
int & ir{i};

它构造一个临时文件,然后将引用绑定到该临时文件。 (并且在上面的示例中,它将失败,因为不能将非常量左值引用绑定到临时对象。)

显然,这绝对没有任何意义。 这是标准中的缺陷。 不幸的是,GCC 4.8至少在构造函数的成员初始值设定项列表中实现了这部分标准。 结果, v_{v}构造了一个临时的std::vector并将该临时绑定到v_ (绑定成功,因为v_是const引用)。 临时的寿命在构造函数的结尾处结束,并引用变得晃来晃去的,这意味着你的第二个out呼叫未定义的行为。

标准缺陷已通过CWG问题1288的解决方案进行了修复,并且此修复程序已在GCC 4.9中实现(请参阅GCC错误50025 )。 如果您坚持使用GCC 4.8,则解决方法是使用旧的初始化语法v_(v)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM