为什么我的 const ref 无效?

Why my const ref becomes invalid?

为什么我的 const ref 在此代码中变得无效以及如何避免这种情况?无法复制,这是我申请的瓶颈

class Foo {
public:
    const std::string& string() const {
        return string;
    }

private:
    std::string string = "asdf";
};

Foo foo;
std::vector<std::pair<const std::string&, int>> invalid;
for (int i = 0; i < 5; i++) {
    invalid.emplace_back(std::make_pair(foo.string(), i);
    // after this line invalid[i].first is invalid
}

make_pair 返回 pair<std::string,int>,而不是 pair<const std::string&, int>,因为标准要求它是那样的。

template <class T1, class T2>
constexpr pair<V1, V2> make_pair(T1&& x, T2&& y);

§ 20.3.3 - 8

Returns: pair<V1, V2>(std::forward<T1>(x), std::forward<T2>(y));

where V1 and V2 are determined as follows: Let Ui be decay_t<Ti> for each Ti. Then each Vi is X& if Ui equals reference_wrapper, otherwise Vi is Ui.

这应该符合标准:

invalid.emplace_back(std::make_pair(std::ref(foo.string()), i));

根据我的说法:

invalid.emplace_back(decltype(invalid)::value_type(foo.string(), i));

Igor Tandetnik 已经指出了您代码中的问题。 FWIW,我认为在任何情况下让容器通过引用来引用其他对象的成员都不是一个好主意——这隐含地依赖于对象的相对寿命。您可以考虑使用 shared_ptr to const string,如下所示:

#include <string>
#include <memory>
#include <vector>                                                                                                                           
class Foo {
public:
    const std::shared_ptr<const std::string> string() const {
        return _string;
    }   

private:
    std::shared_ptr<std::string> _string = std::make_shared<std::string>("asdf");
};  

int main()
{   
    Foo foo;
    std::vector<std::pair<std::shared_ptr<const std::string>, int>> invalid;
    for (int i = 0; i < 5; i++) {
        invalid.emplace_back(std::make_pair(foo.string(), i));
    }   
}