为什么我的const ref变得无效?

时间:2016-03-26 13:37:36

标签: c++ reference invalidation

为什么我的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
}

2 个答案:

答案 0 :(得分:1)

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

     

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

     
    

其中V1V2的确定如下:令每个Ti的Ui为decay_t<Ti>。那么每个Vi都是X&amp;     如果Ui等于reference_wrapper,否则Vi是Ui。

  

这应该按照标准运作:

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

这是根据我的说法:

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

答案 1 :(得分:1)

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));
    }   
}