Фон и предыдущий поиск
Я ищу элегантный способ перебрать итерацию по контейнеру (например, std :: vector), используя основанный на диапазоне цикл for вC ++ 14.В поисках решения я нашел это Q / A .Это в основном говорит мне, что это не является частью стандартной библиотеки, и я должен использовать boost или реализовать адаптер самостоятельно.Я не хочу использовать boost, поэтому сейчас я ищу лучшую собственную реализацию.
Помимо предложений, приведенных в ранее упомянутых Q / A , я также нашел эта реализация и этот блог по этой теме.Большинство реализаций очень похожи и выглядят вполне прилично.Однако у всех них есть подводный камень: как указано в этом комментарии , вы можете получить висячую ссылку, если вызовете обратный адаптер с временным объектом:
for (const auto& v : reverse_iterate(getContainer()))
Относительнопроблема с временным объектом в цикле for на основе диапазона, этот ответ действительно помог мне понять.Но что мы можем сделать, чтобы предотвратить висячую ссылку?
Мое решение
На основе этого фона я ищу реализацию, которая избавит от этой ловушки.В следующей реализации я использую дополнительную ссылку на rvalue rx_
, чтобы продлить время жизни моего входного параметра, если reverse_iterate
вызывается с ссылкой на rvalue.
РЕДАКТИРОВАТЬ: не использовать это решение,Это неверно, как указано в принятом решении.
template <typename T>
class reverse_range
{
T &&rx_; // rvalue-reference to prolong livetime of temporary object
T &x_; // reference to container
public:
explicit reverse_range(T &x) : rx_(T{}), x_(x) {}
explicit reverse_range(T &&rx) : rx_(std::move(rx)), x_(rx_) {}
auto begin() const -> decltype(this->x_.rbegin())
{
return x_.rbegin();
}
auto end() const -> decltype(this->x_.rend())
{
return x_.rend();
}
};
template <typename T>
reverse_range<T> reverse_iterate(T &x)
{
return reverse_range<T>(x);
}
template <typename T>
reverse_range<T> reverse_iterate(T &&rx)
{
return reverse_range<T>(std::move(rx));
}
Очевидно, что мы генерируем небольшие накладные расходы на создание неиспользуемого пустого контейнерного объекта в конструкторе lvalue, но я думаю, что это не так уж плохо.Кроме того, можно, вероятно, избавиться от этого, предоставив два класса reverse_range_lvalue
и reverse_range_rvalue
, каждый из которых обеспечивает реализацию для одного из типов параметров ...
Вопросы
Будет ли указанное выше решение решить проблему с висящими ссылками или я что-то упущу?
Есть ли у вас какие-либо подсказки по дальнейшим проблемам, связанным с моим кодом?
Есть ли лучшие идеи для решения этой проблемыв C ++ 14 или любой другой (будущей) версии?