如果创建对临时变量的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, changes behavior when used as a member和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);