Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding std::forward

Why the compiler is not able to deduce the template parameter for std::forward?

I mean:

#include <memory>
#include <iostream>

struct X{};

struct A{
    A( const X& ) { std::cout << "cpy ctor\n"; }
    A( X&& ) { std::cout << "move ctor\n"; }
};

X foo() { return {}; }

template<typename T,typename Arg>
T* factory( Arg&& a )
{
    return new T(std::forward(a));
    // ----------^^^^^^^^^^^^^^^ error: can't deduce template parameter
}

int main()
{
    factory<A>(foo());
}

I know this is a design choice (due to the std::remove_reference in the definition of std::forward) to avoid the user forget to specify the type. What I can't get is: why the way it's implemented works to prevent deduction? Why the compiler is not just deducing forward's template parameter as Arg.

like image 200
Paolo M Avatar asked Aug 25 '15 13:08

Paolo M


1 Answers

std::forward is declared like so:

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

typename std::remove_reference<T>::type is a non-deduced context. The compiler has no way of knowing which T should be deduced because it doesn't understand the semantic connection between the type member type and a given T. It would need to search through all types to find a match and be able to somehow disambiguate collisions. This is unreasonable, so the standard doesn't allow it.

like image 167
TartanLlama Avatar answered Sep 30 '22 23:09

TartanLlama