Przygotowałem walizkę testową, aby dowiedzieć się o perfekcyjnym przekazywaniu.C++ 11: subtelność std :: forward: Czy tożsamość jest naprawdę potrzebna?
std::string inner(const std::string& str) {
return "const std::string&";
}
std::string inner(std::string& str) {
return "std::string&";
}
std::string inner(const std::string&& str) {
return "const std::string&&";
}
std::string inner(std::string&& str) {
return "std::string&&";
}
template <typename T> void outer(T&& t) {
std::cout << "t: " << t << std::endl;
std::cout << "perfect forward: " << inner(std::forward<T>(t)) << std::endl;
std::cout << std::endl;
}
void PerfectForwarding()
{
outer("literal");
outer(lvalue);
outer(constlvalue);
outer(rvalue());
outer(constrvalue());
}
std::forward
działa zgodnie z oczekiwaniami. Interesującą zachowanie pojawia się, gdy zaimplementować własną funkcję naprzód bez tożsamości:
template <typename T> T&& MyForward(T& t)
{
return ((T&&)t);
}
Wymiana std::forward
z MyForward
w zewnętrznej daje dokładnie ten sam wynik! Zachowanie nasuwa pytanie, dlaczego tożsamość jest używana?
Compiler VS2010
Aktualizacja 1: W odniesieniu do zapobiegania TYP odliczenia
AFAIK, przepis szczególny rodzaj odliczenie jest aktywna tylko na T & &. Zwróć uwagę na definicję forward, forward(typename identity<T>::type& t)
. Typ argumentu ma tylko jedną wartość: &. W rzeczywistości, po zmianie funkcji MyForward na tożsamość i pominięciu rzutowania (T & &), przykład nie zostanie skompilowany. Na powierzchni rzut od l-wartości do rwartości wydaje się sprawiać, że praca naprzód.
Aktualizacja 2: testowane na ideone.com z GCC 4.5, to samo zachowanie.
Co masz na myśli przez "tożsamość"? Dwa przeciążenia typu 'std :: forward' lub' remove_reference :: type'? –
kennytm
Tożsamość określa strukturę tożsamości, typ argumentu forward: _Ty && forward (tożsamość typu <_Ty> :: type & _Arg) –
To musi być jakiś standardowy podpis. Standardowym jest 'T && forward (typename remove_reference :: type & t)' (i przeciążenie przyjmujące '&&'). –
kennytm