const引用是类不一致的成员

时间:2018-08-17 23:29:48

标签: c++ c++11 const-correctness dangling-pointer const-reference

如果创建对临时变量的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 memberhttps://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);

0 个答案:

没有答案