gpt4 book ai didi

c++ - 在 ctor 中使用 const vector 初始化的 const vector 成员

转载 作者:行者123 更新时间:2023-11-30 03:57:03 31 4
gpt4 key购买 nike

我有以下代码,其中有成员 v_,一个常量对整数 vector 的引用。它是用左值初始化的,所以我的认为这不应该引起任何复制。

#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) 因此它试图复制构造传递给构造函数的原始 vector .这是编译器错误还是我以某种方式做了一些未定义或完全错误的事情?

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

最佳答案

C++11 标准实际上说当你像这样列表初始化一个引用时:

int i;
int & ir{i};

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

显然这毫无意义;这是标准的缺陷。不幸的是,GCC 4.8 实现了标准的这一部分,至少在构造函数的成员初始化列表中是这样。结果,v_{v} 构造了一个临时的 std::vector 并将该临时的绑定(bind)到 v_(绑定(bind)成功是因为 v_ 是一个 const 引用);临时对象的生命周期在构造函数结束时结束,引用变为悬空,这意味着您的第二个 out 调用具有未定义的行为。

CWG issue 1288 的决议修复了标准缺陷,并且此修复已在 GCC 4.9 中实现(请参阅 GCC bug 50025)。如果您受困于 GCC 4.8,解决方法是使用旧的初始化语法 v_(v)

关于c++ - 在 ctor 中使用 const vector 初始化的 const vector 成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28162379/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com