如果创建一个对临时对象的 const 引用,它的寿命就会延长,就像引用在堆栈中的位置一样。这是该语言的一个很好的特性,尽管它有时会像其他规则的例外一样出现。 https://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/
但是,当 const 引用是类成员的一部分时,这不起作用。这是语言不一致吗?
示例代码:
int f(int a){return a + 5;}
int main(){
int const& b = f(2);
assert(b == 7); // ok, not a dangling reference
struct single{
int const& m_;
single(int const& m) : m_(m){}
};
single s{f(3)};
assert(s.m_ == 8); // fails, dangling reference
struct pair{
int const& m1_;
int const& m2_;
pair(int const& m1, int const& m2) : m1_(m1), m2_(m2){}
};
pair p{f(3), f(4)};
assert( p.m1_ == 8 ); // fails, dangling reference
}
是否有一种解决方法可以使其工作或至少表现得更一致?
我发现这在现在的一些情况下是一个限制因素。例如,List using with references,在用作成员时更改行为和https://stackoverflow.com/a/51878764/225186
EDIT1:在其他类似问题的答案中提到,问题在于构造函数采用了const&
规则不适用的地方。然而,一个完美的前锋仍然失败。在这种情况下,要么语言的不一致更加明显,要么完美的前锋不那么完美。
struct single{
int const& m_;
template<class T>
single(T&& m) : m_(std::forward<T>(m)){}
};
EDIT2:声明single const& s{f(3)};
仍然无济于事。但是,将常量“移动”到结构会有所帮助。
struct single{
int m_; // no const!
template<class T>
single(T&& m) : m_(std::forward<T>(m)){}
};
...
single const& s{f(3)}; // const ref with extended lifetime
因此,将常量转移到整个结构也许是一种好习惯。
我仍然认为参考成员在语言中的行为很奇怪。https://www.youtube.com/watch?v=uYDt1gCDxhM
EDIT3:正如@Oliv 提到的,如果使用聚合初始化,情况会有所改善。然而,这是相当有限的。
struct single{
int const& m_;
};
...
single s{f(3)};
assert(s.m_ == 5);