Преимущества использования reference_wrapper вместо необработанного указателя в контейнерах?
Какие преимущества имеет использование std::reference_wrapper
в качестве параметра шаблона контейнеров вместо необработанных указателей? Это std::vector<std::reference_wrapper<MyClass> >
vs. std::vector<MyClass*>
Мне нравится забывать о нулях и не использовать синтаксис указателя, но многословие типов (т.е. vector<reference_wrapper<MyClass> >
) плюс использование сайта вызова std:: ref для обертывания фактической ссылки заставляет меня думать, что это не стоит он.
Я имею в виду случаи, когда использование std:: shared_ptr или любого другого интеллектуального указателя не является вариантом.
Существуют ли другие преимущества использования reference_wrapper или любых других факторов, которые я в настоящее время не учитываю? (Я думаю, мой вопрос относится как к С++ 11 reference_wrapper, так и к boost)
Ответы
Ответ 1
Я не думаю, что есть какая-то техническая разница. Справочная оболочка предоставляет базовые функции указателя, включая возможность динамического изменения цели.
Одно из преимуществ заключается в том, что он демонстрирует намерение. Это говорит людям, которые читают код, который "кто имеет" имеет переменную, фактически не контролирует свою продолжительность жизни. Пользователь не забыл удалить или новое что-нибудь, что некоторые люди могут начать искать, когда видят семантику указателя.
Ответ 2
Ссылки C действительно проблематичны при работе с шаблонами. Если вам "повезло" достаточно, чтобы скомпилировать код со ссылкой в качестве параметра шаблона, у вас могут возникнуть проблемы с кодом, который будет работать (по какой-то причине) следующим образом:
template<class T> f(T x) { g(x); }
template<class T> g(T x) { x++; }
Тогда, даже если вы вызовете f<int&>(x)
, он вызовет g<int>
. Но reference_wrapper
отлично работает с шаблонами.
Как уже упоминалось ранее, у вас возникнут проблемы с компиляцией таких вещей, как vector<int&>
, но vector<reference_wrapper<int>>
работает нормально.