2014-09-18 9 views
5

Utworzono alias, który powinien zachowywać się dokładnie tak, jak std::forward.Tworzenie aliasu `std :: forward` - nieoczekiwane wyniki

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

I wtedy zastąpione wszystkie wystąpienia std::forward<...> z fwd<...> w moim kodzie.

Zestawiono wszystkie projekty z g++ 4.9 - wszystkie testy zakończone, wszystko działało poprawnie.

Potem próbowałem kompilacji z clang++ 3.5. Niektóre testy zdawały się losowo zawieść, a powodem było fwd<...>. Zastąpienie go ponownie numerem std::forward<...> naprawiło awarię testów.

Próbowałem pisać fwd<...> ze składnią typu trailing powrotnej, jak myślałem decltype(auto) nie działa:

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

wyniki same: g++ prace, clang++ nie.

Potem spojrzał podpis std::forward na cppreference i realizowane mój alias takiego:

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); } 

To działa (wszystkie testy pass) zarówno na g++ i clang++.

Dlaczego nie działa wersja decltype(auto)? Nie powinien zwracać dokładnie tego samego typu zwrotu, co std::forward?

+3

swoje siły alias kopie dla rvalues ​​zamiast ruchów. – Xeo

+2

Czy próbowałeś użyć 'auto' lub' decltype (auto) 'w dwóch ostatnich implementacjach roboczych zachowując' std :: remove_reference_t' w argumentach? – iFreilicht

Odpowiedz

2

Zapomniałaś zadeklarować M-wartości jako odniesienie przenieść

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); 
} 
+1

Nie jestem pewien, czy 'fwd (T && mValue)' zadziała, jeśli 'T' jest' Type & 'lub' Type && ' – programmerjake

+1

Zauważ, że wersja z odwołaniem do l-wartości jest również potrzebna, gdy masz błąd kompilacji: (http://coliru.stacked-crooked.com/a/3505f7b8b37980e2) – Jarod42

+0

@ Jarod42 naprawiono, dzięki – programmerjake

Powiązane problemy