在C ++中实现SFINAE的方法 [英] Approaches to function SFINAE in C++
问题描述
我在项目中大量使用SFINAE函数,不确定以下两种方法(样式除外)之间是否有任何区别:
I am using function SFINAE heavily in a project and am not sure if there are any differences between the following two approaches (other than style):
#include <cstdlib>
#include <type_traits>
#include <iostream>
template <class T, class = std::enable_if_t<std::is_same_v<T, int>>>
void foo()
{
std::cout << "method 1" << std::endl;
}
template <class T, std::enable_if_t<std::is_same_v<T, double>>* = 0>
void foo()
{
std::cout << "method 2" << std::endl;
}
int main()
{
foo<int>();
foo<double>();
std::cout << "Done...";
std::getchar();
return EXIT_SUCCESS;
}
程序输出符合预期:
method 1
method 2
Done...
我看到方法2在stackoverflow中使用得更频繁,但是我更喜欢方法1.
I have seen method 2 used more often in stackoverflow, but I prefer method 1.
这两种方法有什么不同的情况吗?
Are there any circumstances when these two approaches differ?
推荐答案
我看到方法2在stackoverflow中使用得更频繁,但是我更喜欢方法1.
I have seen method 2 used more often in stackoverflow, but I prefer method 1.
建议:建议使用方法2.
Suggestion: prefer method 2.
这两种方法都可以使用单个功能.当您具有一个以上具有相同签名的功能,并且只想启用集合中的一个功能时,就会出现问题.
Both methods work with single functions. The problem arises when you have more than a function, with the same signature, and you want enable only one function of the set.
假设您要在 bar< T>()
(假设它是 constexpr
函数)时启用版本1的 foo()
.当 bar< T>()
为 false
时,版本2为 true
和 foo()
.
Suppose that you want enable foo()
, version 1, when bar<T>()
(pretend it's a constexpr
function) is true
, and foo()
, version 2, when bar<T>()
is false
.
使用
template <typename T, typename = std::enable_if_t<true == bar<T>()>>
void foo () // version 1
{ }
template <typename T, typename = std::enable_if_t<false == bar<T>()>>
void foo () // version 2
{ }
由于模棱两可而导致编译错误:两个具有相同签名的 foo()
函数(默认模板参数不会更改签名).
you get a compilation error because you have an ambiguity: two foo()
functions with the same signature (a default template parameter doesn't change the signature).
但是以下解决方法
template <typename T, std::enable_if_t<true == bar<T>(), bool> = true>
void foo () // version 1
{ }
template <typename T, std::enable_if_t<false == bar<T>(), bool> = true>
void foo () // version 2
{ }
有效,因为SFINAE修改了功能的签名.
works, because SFINAE modify the signature of the functions.
不相关的观察:还有第三种方法:启用/禁用返回类型(显然,除了类/结构构造函数之外)
Unrelated observation: there is also a third method: enable/disable the return type (except for class/struct constructors, obviously)
template <typename T>
std::enable_if_t<true == bar<T>()> foo () // version 1
{ }
template <typename T>
std::enable_if_t<false == bar<T>()> foo () // version 2
{ }
作为方法2,方法3与具有相同签名的替代功能的选择兼容.
As method 2, method 3 is compatible with selection of alternative functions with same signature.
这篇关于在C ++中实现SFINAE的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!