我已经使用了SFINAE习惯用了很多次,我习惯于把std::enable_if<>模板参数放在模板参数而不是返回类型中.但是,我遇到了一些不起作用的琐碎案例,我不知道为什么.首先,这是我的主要内容:
int main()
{
foo(5);
foo(3.4);
}
Run Code Online (Sandbox Code Playgroud)
这是一个foo触发错误的实现:
template<typename T,
typename = typename std::enable_if<std::is_integral<T>::value>::type>
auto foo(T)
-> void
{
std::cout << "I'm an integer!\n";
}
template<typename T,
typename = typename std::enable_if<std::is_floating_point<T>::value>::type>
auto foo(T)
-> void
{
std::cout << "I'm a floating point number!\n";
}
Run Code Online (Sandbox Code Playgroud)
这是一个可以正常工作的等效代码:
template<typename T>
auto foo(T)
-> typename std::enable_if<std::is_integral<T>::value>::type
{
std::cout << "I'm an integrer!\n";
}
template<typename T>
auto foo(T)
-> typename std::enable_if<std::is_floating_point<T>::value>::type
{
std::cout << "I'm a floating point number!\n";
}
Run Code Online (Sandbox Code Playgroud)
我的问题是:为什么第一次执行 …
我遇到了关于enable_if和模板特化的适当用法的问题.
修改示例后(出于保密原因),这是一个类似的例子:
我有一个名为"less"的函数,用于检查1st arg是否小于2nd arg.假设我想根据输入的类型有两种不同的实现 - 一个是整数实现,另一个是double.
到目前为止我的代码看起来像这样 -
#include <type_traits>
#include <iostream>
template <class T,
class = typename std::enable_if<std::is_floating_point<T>::value>::type>
bool less(T a, T b) {
// ....
}
template <class T,
class = typename std::enable_if<std::is_integral<T>::value>::type>
bool less(T a, T b) {
// ....
}
int main() {
float a;
float b;
less(a,b);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
上面的代码没有编译,因为 - 它说我正在重新定义less方法.
错误是:
Z.cpp:15:19: error: template parameter redefines default argument
class = typename std::enable_if<std::is_integral<T>::value>::type>
^
Z.cpp:9:19: note: previous default template argument defined here …Run Code Online (Sandbox Code Playgroud) 假设我们有一些SFINAE成员函数:
class foo{
template <class S, class = std::enable_if_t<std::is_integral<S>::value, S>
void bar(S&& s);
template <class S, class = std::enable_if_t<!std::is_integral<S>::value, S>
void bar(S&& s);
}
Run Code Online (Sandbox Code Playgroud)
如果我们如上所述,那么我们如何定义它们呢?他们的两个功能签名看起来像:
template <class S, class>
inline void foo::bar(S&& s){ ... do something ... }
Run Code Online (Sandbox Code Playgroud)
我已经看到了一个返回std::enable_if_t<...>类似的例子:
template <class S, class>
auto bar(S&& s) -> std::enable_if_t<!std::is_integral<S>::value, S>(...){
... do something ...
}
Run Code Online (Sandbox Code Playgroud)
基于返回类型消除歧义.但我不想退货.