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
.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With