In a method overload situation like this:
struct A
{
void foo( int i ) { /*...*/ }
template<typename T> void foo( T t ) { /*...*/ }
}
How can I prevent template instantiation unless explicitly commanded?:
A a;
a.foo<int>( 1 ); // ok
a.foo<double>( 1.0 ); // ok
a.foo( 1 ); // calls non-templated method
a.foo( 1.0 ); // error
Thanks!
You can introduce a depedent_type
struct that prevents template argument deduction.
template <typename T>
struct dependent_type
{
using type = T;
};
struct A
{
void foo( int i ) { /*...*/ };
template<typename T> void foo( typename dependent_type<T>::type t ) { /*...*/ }
}
Which in your example:
a.foo<int>( 1 ); // calls the template
a.foo<double>( 1.0 ); // calls the template
a.foo( 1 ); // calls non-templated method
a.foo( 1.0 ); // calls non-templated method (implicit conversion)
wandbox example
(This behavior is explained on cppreference > template argument deduction > non-deduced contexts.)
If you want to make a.foo( 1.0 )
a compilation error, you need to constrain the first overload:
template <typename T>
auto foo( T ) -> std::enable_if_t<std::is_same<T, int>{}> { }
This technique makes the above overload of foo
take only int
arguments: implicit conversions (e.g. float
to int
) are not allowed. If this is not what you want, consider TemplateRex's answer.
wandbox example
(With the above constrained function, there is a curious interaction between the two overloads when a.foo<int>( 1 )
is called. I asked a question about it as I'm not sure of the underlying rules that guide 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