Я пишу библиотеку, которая обертывает множество функций и методов из другой библиотеки. Чтобы избежать совпадения возвращаемых значений, я применяю std::forward
следующим образом:
template<class T>
T&& wrapper(T&& t) {
f(t); // t passed as lvalue
return std::forward<T>(t);
}
f
возвращает void
и принимает T&&
(или перегружен по значению). Wrapper всегда возвращает параметр wrappers param, а возвращаемое значение должно сохранять нечеткость аргумента. Мне действительно нужно использовать std::forward
в return
? RVO делает его излишним? Означает ли факт, что это ссылка (R или L), делает ее излишней? Нужно ли это, если возврат не является последним оператором функции (внутри некоторого if)?
Это спорно, если wrapper()
должен возвращать void
или T&&
, потому что вызывающий абонент имеет доступ к оцененному значению через Arg (который является ссылка, R или L). Но в моем случае мне нужно вернуть значение, чтобы wrapper()
можно было использовать в выражениях.
Это может быть неуместно в вопросе, но известно, что функции f
не воруют из t
, поэтому 1-е использование std::forward
в f(std::forward<T>(t))
является излишним, и оно было удалено мной.
Я написал небольшой тест: https://gist.github.com/3910503
Тест показывает, что возвращение непредвиденного t
- создает дополнительную копию в gcc48 и clang32 с -O3 (RVO не срабатывает).
Кроме того, я не смог получить плохое поведение от UB в:
auto&& tmp = wrapper(42);
Это ничего не доказывает, потому что это поведение undefined (если это UB).