I do not understand why the following simple example fails:
#include <boost/hana.hpp>
template <typename _T>
static constexpr void Foo(boost::hana::type<_T>) {
}
int main() {
Foo(boost::hana::type_c<int>);
return 0;
}
I get the following error message:
[build] error: no matching function for call to ‘Foo(boost::hana::type<int>&)’
[build] 74 | Foo(hana::type_c<int>);
[build] | ~~~^~~~~~~~~~~~~~~~~~~
[build] note: candidate: ‘template<class _T> constexpr void Morphy::Foo(boost::hana::type<T>)’
[build] 61 | static constexpr void Foo(hana::type<_T>) {
[build] | ^~~
[build] note: template argument deduction/substitution failed:
[build] note: couldn’t deduce template parameter ‘_T’
[build] 74 | Foo(hana::type_c<int>);
[build] | ~~~^~~~~~~~~~~~~~~~~~~
The only way to make the above work is by making explicit the template argument of Foo
by writing Foo<int>(boost::hana::type_c<int>)
. Why is the compiler unable to automatically deduce the template argument?
Notice that the above code works if I use boost::hana::basic_type
in place of boost::hana::type
in the declaration of Foo
. Is this alternative approach correct?
CodePudding user response:
type_c<int>
is a variable template that creates a value of type type<int>
. It indeed seems like Foo
should easily deduce parameter _T
from type<_T>
when passing type<int>
. However it is not possible because type
is an alias template that refers to member of some auxiliary class and its parameter is always in non-deduced context.
template< typename x_Type >
struct FooImpl
{
using Type = x_Type;
};
template< typename x_Type >
using Foo = typename FooImpl<x_Type>::Type;
template< typename x_Type > // x_Type can not be deduced
void Bar(Foo<x_Type>) {}
int main()
{
Bar(Foo<int>{});
return 0;
}
basic_type
works because it is an actual type of type_c
.