繁体   English   中英

使用std :: enable_if作为函数参数和模板参数有什么区别?

[英]What is the difference between using std::enable_if as function argument vs template argument?

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

我有以下2个功能模板:

#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不是可接受的类型)而无法编译, f_template即使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)
{ }

所有这些都按预期工作,你不能解决它们(至少,我不知道如何做到这一点,但也许有人会有一个很好的技巧)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM