SFINAE 无法有条件地编译成员函数模板
SFINAE not working to conditionally compile member function template
我正在尝试使用 std::enable_if
使用 SFINAE 和以下代码有条件地仅从两个成员函数模板中选择一个:
#include <iostream>
#include <type_traits>
template<typename T>
struct C {
template<typename Q = T, typename = typename std::enable_if<std::is_same<Q, int>::value>::type>
int foo() {
return 1;
}
template<typename Q = T, typename = typename std::enable_if<!std::is_same<Q, int>::value>::type>
int foo() {
return 0;
}
};
int main() {
std::cout << C<int>().foo() << std::endl; //error member function foo already defined
}
但出于某种原因,visual c++ 不断给我一个编译器错误,提示 foo
已定义。尽管如此,很明显,根据 class' 模板参数,只有一个函数是格式正确的。所以 SFINAE 应该把第二个从考虑中去掉。
知道为什么这不起作用吗?
试试
template<typename T>
struct C {
template<typename Q = T,
typename std::enable_if<std::is_same<Q, int>::value, bool>::type = true>
int foo() { // .............................................^^^^^^^^^^^^^^^^^^^^
return 1;
}
template<typename Q = T,
typename std::enable_if<!std::is_same<Q, int>::value, bool>::type = true>
int foo() { // ..............................................^^^^^^^^^^^^^^^^^^^^
return 0;
}
};
重点是在您的代码中 SFINAE 将 enable/disable 模板类型参数的默认值;但默认值不参与重载决策,因此,在您的情况下,您有两个函数
template<typename, typename = void>
int foo() {
return 1;
}
template<typename, typename>
int foo() {
return 0;
}
具有相同的签名;所以编译器无法在两者之间进行选择,会报错。
我提出的代码是不同的,因为万一 std::enable_if
的测试是假的,你没有类型(=
左边的元素),而不是值.东西如
// ................VVVVVV what is = true ?
template<typename, = true>
int foo() {
return 1;
}
这是一个真正的 "substitution failure" 禁用该方法。
我正在尝试使用 std::enable_if
使用 SFINAE 和以下代码有条件地仅从两个成员函数模板中选择一个:
#include <iostream>
#include <type_traits>
template<typename T>
struct C {
template<typename Q = T, typename = typename std::enable_if<std::is_same<Q, int>::value>::type>
int foo() {
return 1;
}
template<typename Q = T, typename = typename std::enable_if<!std::is_same<Q, int>::value>::type>
int foo() {
return 0;
}
};
int main() {
std::cout << C<int>().foo() << std::endl; //error member function foo already defined
}
但出于某种原因,visual c++ 不断给我一个编译器错误,提示 foo
已定义。尽管如此,很明显,根据 class' 模板参数,只有一个函数是格式正确的。所以 SFINAE 应该把第二个从考虑中去掉。
知道为什么这不起作用吗?
试试
template<typename T>
struct C {
template<typename Q = T,
typename std::enable_if<std::is_same<Q, int>::value, bool>::type = true>
int foo() { // .............................................^^^^^^^^^^^^^^^^^^^^
return 1;
}
template<typename Q = T,
typename std::enable_if<!std::is_same<Q, int>::value, bool>::type = true>
int foo() { // ..............................................^^^^^^^^^^^^^^^^^^^^
return 0;
}
};
重点是在您的代码中 SFINAE 将 enable/disable 模板类型参数的默认值;但默认值不参与重载决策,因此,在您的情况下,您有两个函数
template<typename, typename = void>
int foo() {
return 1;
}
template<typename, typename>
int foo() {
return 0;
}
具有相同的签名;所以编译器无法在两者之间进行选择,会报错。
我提出的代码是不同的,因为万一 std::enable_if
的测试是假的,你没有类型(=
左边的元素),而不是值.东西如
// ................VVVVVV what is = true ?
template<typename, = true>
int foo() {
return 1;
}
这是一个真正的 "substitution failure" 禁用该方法。