为什么这种简单地使用 SFINAE 和类型特征来重载函数模板会导致模棱两可的调用?
Why does this simple use of SFINAE & type traits to overload a function template leads to ambiguous call?
我正在尝试使用类型特征为特定函数提供几个重载,这样我就不必在调用所述函数时指定模板参数,并且它可以用于任何数据类型和不同类型的容器:
#include <type_traits>
#include <vector>
#include <initializer_list>
template< typename T, typename = std::enable_if< std::is_arithmetic< T >::value > >
bool myFunction(const std::vector< T >& data) {
// ...
return true;
}
template < typename T, typename = std::enable_if< !std::is_arithmetic< T >::value >, typename = void >
bool myFunction(const std::vector< T >& data) {
// ...
return true;
}
template< typename T >
bool myFunction(const std::initializer_list< T >& data) {
return myFunction< T >(std::vector< T >(data));
}
int main(int argc, char const *argv[]) {
std::vector< float > data = { };
myFunction(data); // error: call of overloaded ‘myFunction(std::vector<float>&)’ is ambiguous
return 0;
}
但是,在尝试编译这段代码时,我收到一个错误,抱怨调用不明确。我到底错过了什么?第二个模板参数不应该确保对于任何 T
,只声明一个 myFunction
吗?
这应该是 std::enable_if_t
而不是 std::enable_if
。或者因为你标记了 C++11,你可以做 std::enable_if<...>::type
std::enable_if<false>
不是替换失败,只有 std::enable_if<false>::type
是。
我正在尝试使用类型特征为特定函数提供几个重载,这样我就不必在调用所述函数时指定模板参数,并且它可以用于任何数据类型和不同类型的容器:
#include <type_traits>
#include <vector>
#include <initializer_list>
template< typename T, typename = std::enable_if< std::is_arithmetic< T >::value > >
bool myFunction(const std::vector< T >& data) {
// ...
return true;
}
template < typename T, typename = std::enable_if< !std::is_arithmetic< T >::value >, typename = void >
bool myFunction(const std::vector< T >& data) {
// ...
return true;
}
template< typename T >
bool myFunction(const std::initializer_list< T >& data) {
return myFunction< T >(std::vector< T >(data));
}
int main(int argc, char const *argv[]) {
std::vector< float > data = { };
myFunction(data); // error: call of overloaded ‘myFunction(std::vector<float>&)’ is ambiguous
return 0;
}
但是,在尝试编译这段代码时,我收到一个错误,抱怨调用不明确。我到底错过了什么?第二个模板参数不应该确保对于任何 T
,只声明一个 myFunction
吗?
这应该是 std::enable_if_t
而不是 std::enable_if
。或者因为你标记了 C++11,你可以做 std::enable_if<...>::type
std::enable_if<false>
不是替换失败,只有 std::enable_if<false>::type
是。