用例:我正在将数据从我的一个非常旧的程序转换为数据库友好格式。有些部分我必须对旧数据进行多次传递,因为特别是在我可以在关系中引用它们之前,键必须首先存在。所以我想为什么不在第一次通过时将不完整的部分放在引用向量中并从工作函数中返回,这样我就可以轻松地使用该向量对仍然不完整的部分进行第二次传递。我喜欢尽可能避免使用指针,所以我研究了std::reference_wrapper<T>
这似乎正是我需要的......除了我根本不明白它的行为。
我两者都有vector<OldData> old_data
,并且vector<NewData> new_data
是我的转换班的成员。转换成员函数本质上是:
//...
vector<reference_wrapper<NewData>> incomplete;
for(const auto& old_elem : old_data) {
auto& new_ref = *new_data.insert(new_data.end(), convert(old_elem));
if(is_incomplete(new_ref)) incomplete.push_back(ref(new_ref));
}
return incomplete;
但是,在循环incomplete
之后立即被打破。for
该程序编译,但崩溃并产生乱码。现在我不知道我ref
是否正确放置,但这只是我尝试将它放在其他地方的众多尝试之一,使用push_back
或emplace_back
代替等。.. 似乎有些东西超出了范围,但是什么?两者都是类成员,new_data
也存在于循环之外,并且根据文档,是可复制的。old_data
incomplete
reference_wrapper
这是一个简化的 MWE,它编译、崩溃并产生乱码:
// includes ..
using namespace std;
int main() {
int N = 2; // works correctly for N = 1 without any other changes ... ???
vector<string> strs;
vector<reference_wrapper<string>> refs;
for(int i = 0; i < N; ++i) {
string& sref = ref(strs.emplace_back("a"));
refs.push_back(sref);
}
for (const auto& r : refs) cout << r.get(); // crash & gibberish
}
如果这意味着什么g++ 10.2.0
。-std=c++17
现在我可能只使用指针并完成,但我想了解这里发生了什么,文档/搜索似乎没有帮助..