![](/img/trans.png)
[英]error: undefined reference to `vector<int>::pushBack(int 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.