Почему мой const ref становится недействительным?

Почему мой 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
}

0

Решение

Игорь Тандетник уже указал на проблему в вашем коде. FWIW, я не думаю, что это хорошая идея, чтобы контейнеры ссылались на элементы других объектов по ссылке в любом случае — есть неявная зависимость от относительного времени жизни объектов. Вы можете рассмотреть возможность использования shared_ptr в 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));
}
}
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));

где V1 а также V2 определяются следующим образом: пусть Ui будет decay_t<Ti> за каждый ти. Тогда каждый Vi есть X&
если 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

По вопросам рекламы [email protected]