Mik*_*ail 13 c++ pass-by-reference c++11
这听起来像一个基本问题,但我没有找到任何全面的答案,所以在这里.请考虑以下代码段:
struct A {
const std::string& s;
A(const std::string& s) : s(s) {}
};
int main() {
A a("abc");
std::cout << a.s << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
演示.
只要我明白,这就是UB.字符串文字"abc"绑定到const std::string&构造函数中,创建一个临时字符串对象.它也必须引用a.s,并且一旦a被构造就被销毁.也就是说,const引用不能链延长寿命延长.晃来晃去参考,热潮.在这个特殊情况下,我在ideone.com上看不到任何输出,但任何事情都可能发生(请记住速龙).
好的,这个很清楚.但是,如果这实际上是我们的意图呢:我们想要存储对象的const引用?对现有的,不是暂时的?这听起来像是一项非常自然的任务,但我只想出一个(几乎)自然的解决方案.接受构造函数的参数std::reference_wrapper而不是引用:
A(std::reference_wrapper<const std::string> r) : s(r) {}
Run Code Online (Sandbox Code Playgroud)
既然std::reference_wrapper删除了临时的构造函数:
reference_wrapper( T&& x ) = delete;
Run Code Online (Sandbox Code Playgroud)
这个工作就像预期一样.但是,这并不是很优雅.我能想到的另一种方法是接受转发引用T&&并拒绝除const l-value字符串之外的所有内容std::enable_if.我认为这更不优雅.
还有其他方法吗?
UPD另一个问题:这是合法使用std::reference_wrapper,还是可能被认为过于具体?
我想说,自然的解决方案是去做reference_wrapper:防止临时建筑:
struct A {
const std::string& s;
A(const std::string& s) : s(s) {}
A(std::string&&) = delete;
};
Run Code Online (Sandbox Code Playgroud)
您还应该记住,默认情况下,具有引用类型的数据成员会使该类不可分配(甚至无法进行移动分配),并且通常很难实现分配运算符。您应该考虑存储指针而不是引用:
struct A {
const std::string* s;
A(const std::string& s) : s(&s) {}
A(std::string&&) = delete;
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1326 次 |
| 最近记录: |