Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I'm reading Overview of the New C++ (C++11/14) (PDF only), at Slide 288 it gives an implementation of std::forward:

template<typename T>                // For lvalues (T is T&),
T&& std::forward(T&& param)         // take/return lvalue refs.
{                                   // For rvalues (T is T),
    return static_cast<T&&>(param); // take/return rvalue refs.
}

And then gives another implemention in text:

The usual std::forward implementation is:

template<typename T>
struct identity {
    typedef T type;
};
template<typename T>
T&& forward(typename identity<T>::type&& param)
{
    return static_cast<identity<T>::type&&>(param);
}

What is the difference? Why is latter the usual implementation?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
286 views
Welcome To Ask or Share your Answers For Others

1 Answer

The problem with the first is that you can write std::forward(x), which doesn't do what you want, since it always produces lvalue references.

The argument in the second case is a non-deduced context, preventing automatic deduction of the template argument. This forces you to write std::forward<T>(x), which is the right thing to do.

Also, the argument type for the second overload should be typename identity<T>::type& because the input to idiomatic use of std::forward is always an lvalue.

Edit: The standard actually mandates a signature equivalent to this one (which, incidentally, is exactly what libc++ has):

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...