cyb*_*rro 6 c++ templates overloading overload-resolution
在像这样的方法过载情况:
struct A
{
void foo( int i ) { /*...*/ }
template<typename T> void foo( T t ) { /*...*/ }
}
Run Code Online (Sandbox Code Playgroud)
除非明确命令,否则如何防止模板实例化?:
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
Run Code Online (Sandbox Code Playgroud)
谢谢!
您可以引入一个depedent_type防止模板参数推断的结构.
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 ) { /*...*/ }
}
Run Code Online (Sandbox Code Playgroud)
在你的例子中:
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)
Run Code Online (Sandbox Code Playgroud)
(此行为在cppreference > 模板参数推导 > 非推导的上下文中进行了解释.)
如果要a.foo( 1.0 )编译错误,则需要约束第一个重载:
template <typename T>
auto foo( T ) -> std::enable_if_t<std::is_same<T, int>{}> { }
Run Code Online (Sandbox Code Playgroud)
这种技术使得上面的重载foo仅采用int参数:不允许隐式转换(例如floatto int).如果这不是您想要的,请考虑TemplateRex的答案.
(使用上面的约束函数,a.foo<int>( 1 )调用时两个重载之间存在一种奇怪的交互.我问了一个关于它的问题,因为我不确定引导它的基本规则.)