【问题标题】:Difference between two template code patterns where in one case a number is assigned whereas in the other the keyword typename is used两种模板代码模式之间的区别,在一种情况下分配一个数字,而在另一种情况下使用关键字 typename
【发布时间】:2020-09-03 19:51:54
【问题描述】:

在下面的代码中,下面两个模板行有什么区别。

>      1. template<class T, std::enable_if_t<std::is_integral<T>::value, int> = 0> 
>      2. template<class T, typename = std::enable_if_t<std::is_integral<T>::value>>

以上两行都运行良好,我只是想知道使用其中一个的优点/缺点。

#include <type_traits>
#include <iostream>
template<class T, std::enable_if_t<std::is_integral<T>::value, int> = 0>

//template<class T, typename = std::enable_if_t<std::is_integral<T>::value>>


int onlyOnInt(T a, T b)
{
    return a+b;
}
int main()
{
    onlyOnInt(1, 2);
}

【问题讨论】:

    标签: c++ templates c++14 sfinae


    【解决方案1】:

    如果您编写一个函数,它们都可以正常工作。

    但是当你想要两个替代功能时,这样

    template <typename T, typename = std::enable_if_t<true == std::is_integral_v<T>>>
    void foo (T const &)
     { std::cout << "is integral" << std::endl; }
    
    template <typename T, typename = std::enable_if_t<false == std::is_integral_v<T>>>
    void foo (T const &)
     { std::cout << "isn\'t integral" << std::endl; }
    

    在这种情况下会出现编译错误

    template <typename T, std::enable_if_t<true == std::is_integral_v<T>, int> = 0>
    void foo (T const &)
     { std::cout << "is integral" << std::endl; }
    
    template <typename T, std::enable_if_t<false == std::is_integral_v<T>, int> = 0>
    void foo (T const &)
     { std::cout << "isn\'t integral" << std::endl; }
    

    有效。

    原因?

    考虑一下你在玩 SFINAE,即 Substitution Failure Is Not An Error。

    重点是替换。

    第一种方式,当你调用时

    foo(0)
    

    替换带来

    template <typename T, typename = void>
    void foo (T const &)
     { std::cout << "is integral" << std::endl; }
    
    template <typename T, typename>
    void foo (T const &)
     { std::cout << "isn\'t integral" << std::endl; }
    

    也就是说...您有两个具有相同签名的函数(默认模板参数不会更改函数的签名)和调用它的冲突。

    第二种方式你只有

    template <typename T, int = 0>
    void foo (T const &)
     { std::cout << "is integral" << std::endl; }
    

    因为第二个函数中的替换失败使该函数无法使用并被丢弃。所以你只有一个可用的函数,没有碰撞。

    【讨论】:

    • 明确说明
    猜你喜欢
    • 1970-01-01
    • 2017-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-01
    • 1970-01-01
    相关资源
    最近更新 更多