SFINAE 技术是使用默认类来启用/禁用功能。但是,这不适用于重载函数,导致“模板参数重新定义默认参数”:
template <class T, class = std::enable_if_t<std::is_integral_v<T>>>
auto foo(T) { return 1; }
template <class T, class = std::enable_if_t<std::is_floating_point_v<T>>>
auto foo(T) { return 2; }
// error template parameter redefines default argument"
Run Code Online (Sandbox Code Playgroud)
常见的解决方案是使用默认的非类型模板参数:
template <class T, std::enable_if_t<std::is_integral_v<T>, int> = 0>
auto foo(T) { return 1; }
template <class T, std::enable_if_t<std::is_floating_point_v<T>, int> = 0>
auto foo(T) { return 2; }
// works
Run Code Online (Sandbox Code Playgroud)
这仅在条件“不同”时才有效。但是理解什么时候条件“不同”并不是那么简单。
从最明显的例子开始(相同(token by token)条件):
template <class T, std::enable_if_t<std::is_integral_v<T>, T> = 0>
auto foo(T) { return 1; }
template …Run Code Online (Sandbox Code Playgroud)