struct BLA
{
};
template<typename T>
class DUMMY
{
public:
DUMMY() = default;
template<typename U = T, typename = void>
void someFunction()
{
std::cout << std::is_same<U, BLA>::value << "\n";
std::cout << "someFunction() - DEFAULT\n";
}
template<typename U = T, typename std::enable_if<std::is_same<U, BLA>::value, void>::type>
void someFunction()
{
std::cout << "someFunction()\n";
}
};
int main()
{
DUMMY<BLA> dummy;
dummy.someFunction();
}
为什么此SFINAE代码调用显示“ someFunction()-DEFAULT”的someFunction()?它应该调用另一个。显然,std :: is_same :: value是true。
我正在写新答案,因为它不适合发表评论。除了@ Jarod42。
似乎您认为
template<typename U = T, typename std::enable_if<std::is_same<U, BLA>::value, void>::type>
替换为
template<typename U = T, typename = void>
但不是。替代
template<typename U = T, void>
。
因此,您应该将其声明为
template<typename U = T, typename = typename std::enable_if<std::is_same<U, BLA>::value, void>::type>
。
因为您使用的typename
用于指定类型是从属类型,而不是用于模板参数声明。但是无论如何,它们都不起作用。一个静默删除格式不正确的代码,另一个导致相同功能的多个声明。
在您发表评论后,我尝试解释更详细。
template<typename U = T, typename std::enable_if<std::is_same<U, BLA>::value, void>::type>
void someFunction()
{
std::cout << "someFunction()\n";
}
[如果为T == BLA
,则U
变为BLA
,并且使std::is_same< U , BLA>::value
true
。所以结果看起来像这样
template<typename U = BLA, void>
[如果为T == NotBlaType
,则U
变为BLA
并成为std::is_same<U,BLA>::value
。因此结果看起来又像这样
template<typename U = NotBlaType, void>
但是在两种情况下,均未声明该函数。因为不能将void
用作non-type template parameter。
但是如果我们将void
更改为int
,则可以使用。这就是int
起作用的原因。
[template<void = 2>
不合法。
template<int = 2>
是合法的。
使声明有效后,应有条件地切换函数的声明。这就是@ Jarod42答案中的两个函数都具有std::enable_if
来评估彼此求反的原因。
template<typename U = T, typename std::enable_if<std::is_same<U, BLA>::value, void>::type>
将会导致(正确替换)template<typename U = T, void>
无效。
您可能会更改为
template<typename U = T, typename std::enable_if<std::is_same<U, BLA>::value, int>::type = 0>
但是然后,这两个功能都是可行的,因此模棱两可。
所以,您最终可能会这样做
template<typename U = T, typename std::enable_if<!std::is_same<U, BLA>::value, int>::type = 0>
void someFunction()
{
std::cout << std::is_same<U, BLA>::value << "\n";
std::cout << "someFunction() - DEFAULT\n";
}
template<typename U = T, typename std::enable_if<std::is_same<U, BLA>::value, int>::type = 0>
void someFunction()
{
std::cout << "someFunction()\n";
}
在C ++ 17中,更容易做到
void someFunction()
{
if constexpr (std::is_same<U, BLA>::value) {
std::cout << "someFunction()\n";
} else {
std::cout << std::is_same<U, BLA>::value << "\n";
std::cout << "someFunction() - DEFAULT\n";
}
}