在C ++中实现SFINAE的方法 [英] Approaches to function SFINAE in C++

查看:45
本文介绍了在C ++中实现SFINAE的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在项目中大量使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆