Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

what is the difference between forward<T>(a) and (T&&)(a)

Tags:

c++

c++11

template<typename T>  
void outer(T&& t) {inner(forward<T>(t));}  

template<typename T>  
void outer(T&& t) {inner((T&&)(t));}  

what is the difference?

like image 854
chiyer Avatar asked Dec 02 '12 09:12

chiyer


2 Answers

There is no practical difference. std::forward<T>(v) is specified as static_cast<T&&>(v).

§20.2.3 [forward]

template <class T> T&& forward(typename remove_reference<T>::type& t) noexcept;
template <class T> T&& forward(typename remove_reference<T>::type&& t) noexcept;

2 Returns: static_cast<T&&>(t).

A C-style cast goes through most C++-style casts to determine the first working one. One of them is static_cast, which also is the first one that works in this case.

§5.4 [expr.cast] p4

The conversions performed by

  • a const_cast (5.2.11),
  • a static_cast (5.2.9),
  • a static_cast followed by a const_cast,
  • a reinterpret_cast (5.2.10), or
  • a reinterpret_cast followed by a const_cast,

can be performed using the cast notation of explicit type conversion. [...] If a conversion can be interpreted in more than one of the ways listed above, the interpretation that appears first in the list is used, even if a cast resulting from that interpretation is ill-formed.

I'd advise to stick with std::forward, though. The intent is clear from the name and and people will know what it does much more likely than knowing what a weird static_cast<T&&> (or even (T&&)) does.

like image 181
Xeo Avatar answered Oct 13 '22 16:10

Xeo


There is no effective difference. Here is how VC++ defines forward<> for rvalue references:

template<class _Ty> inline
    _Ty&& forward(typename remove_reference<_Ty>::type&& _Arg) _NOEXCEPT
    { // forward anything
        static_assert(!is_lvalue_reference<_Ty>::value, "bad forward call");
        return (static_cast<_Ty&&>(_Arg));
    }
like image 41
Jive Dadson Avatar answered Oct 13 '22 17:10

Jive Dadson