c++ - 使用 std::enable_if 作为函数参数与模板参数有什么区别?

标签 c++ templates metaprogramming function-templates default-arguments

我想知道使用 std::enable_if 有什么区别?作为函数参数还是模板参数?

我有以下两个函数模板:

#include <type_traits>

template<typename T>
void f_function(T, typename std::enable_if_t<std::is_pod<T>::value, int> = 0)
{
}

template<typename T, typename = typename std::enable_if_t<std::is_pod<T>::value>>
void f_template(T)
{
}

int main()
{
  int x = 1;
  f_function(x);
  f_template(x);
}

产生以下程序集(从 https://godbolt.org/g/ON4Rya 开始):

main:
        pushq   %rbp
        movq    %rsp, %rbp
        subq    $16, %rsp
        movl    $1, -4(%rbp)
        movl    -4(%rbp), %eax
        movl    $0, %esi
        movl    %eax, %edi
        call    void f_function<int>(int, std::enable_if<std::is_pod<int>::value, int>::type)
        movl    -4(%rbp), %eax
        movl    %eax, %edi
        call    void f_template<int, void>(int)
        movl    $0, %eax
        leave
        ret
void f_function<int>(int, std::enable_if<std::is_pod<int>::value, int>::type):
        pushq   %rbp
        movq    %rsp, %rbp
        movl    %edi, -4(%rbp)
        movl    %esi, -8(%rbp)
        nop
        popq    %rbp
        ret
void f_template<int, void>(int):
        pushq   %rbp
        movq    %rsp, %rbp
        movl    %edi, -4(%rbp)
        nop
        popq    %rbp
        ret

除了 f_function 有 2 个函数参数和 f_template 有 2 个模板参数的明显区别之外,它们之间还有什么区别?有什么特别的用途吗?

最佳答案

作为一个简单的例子,您可以这样做:

int main() {
    // f_function(std::string{}); // (1)
    // f_template<std::string>(std::string{}); // (2)
    f_template<std::string, void>(std::string{});
}

虽然 (1)(2) 因显而易见的原因而无法编译(std::string 不是可接受的类型),即使 T 不是 pod 类型,f_template 也可以与技巧一起使用。


一个有效的替代方案是:

template<typename T, std::enable_if_t<std::is_pod<T>::value>* = nullptr>
void f_template(T)
{ }

另一个可能是:

template<typename T>
std::enable_if_t<std::is_pod<T>::value>
f_template(T)
{ }

一个更晦涩的例子,它涉及一个参数包作为守卫:

template<typename T, typename..., typename = typename std::enable_if_t<std::is_pod<T>::value>>
void f_template(T)
{ }

所有这些都按预期工作,你无法绕过它们(至少,我不知道该怎么做,但也许有人会想出一个好办法)。

关于c++ - 使用 std::enable_if 作为函数参数与模板参数有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37925584/

相关文章:

c++ - 在 C++14 中使用 hana::transform 转换元组内部的类型

metaprogramming - 宏和字符串插值 (Julia)

c++ - 从链表中删除节点(递归)

c++ - QtCreator : is it possible to debug remote GUI app? (GDB)

c++ - 类模板和仿函数

c++ - C++ 编译时整数变量的最小值和最大值

javascript - 返回按钮从 javascript 模板加载相关的 html

metaprogramming - 使用元编程在 Julia 中声明顶级变量

c++ - 从我的二维数组中的一列返回的字符串值被压缩成一个字符串(在 Mac 操作系统上打开 Windows txt 文件)

c++ - RegOpenCurrentUser 的工作示例