Creating an alias of `std :: forward` - unexpected results

I created the alias std::forward , which should behave exactly like std::forward .

 template<class T> constexpr decltype(auto) fwd(T mValue) noexcept { return std::forward<T>(mValue); } 

Then I replaced all occurrences of std::forward<...> with fwd<...> in my codebase.

Compiled all projects using g++ 4.9 - all tests passed, everything worked correctly.

Then I tried to compile using clang++ 3.5 . Some tests seemed to randomly fail, and the reason was fwd<...> . Replacing it with std::forward<...> again eliminated the failed tests.

I tried writing fwd<...> with the return type syntax, as I thought decltype(auto) not working:

 template<class T> constexpr auto fwd(T mValue) noexcept -> decltype(std::forward<T>(mValue)) { return std::forward<T>(mValue); } 

Same results: g++ works, clang++ no.

Then I looked at the signature of std::forward on cppreference and implemented my alias as follows:

 template<class T> constexpr T&& fwd(std::remove_reference_t<T>& t) { return std::forward<T>(t); } template<class T> constexpr T&& fwd(std::remove_reference_t<T>&& t) { return std::forward<T>(t); } 

This works (all tests pass) on both g++ and clang++ .

Why does the decltype(auto) version not work? Shouldn't the same return type be returned as std::forward ?

+5
source share
1 answer

You forgot to declare mValue a reference to move

 template <typename T> constexpr decltype(auto) fwd(std::remove_reference_t<T> &&mValue) { return std::forward<T>(mValue); } template <typename T> constexpr decltype(auto) fwd(std::remove_reference_t<T> &mValue) { return std::forward<T>(mValue); } 
+2
source

Source: https://habr.com/ru/post/1202864/


All Articles