【问题标题】:SFINAE : Delete a function with the same prototypeSFINAE : 删除具有相同原型的函数
【发布时间】:2018-10-30 14:36:43
【问题描述】:

我想知道这段代码有什么区别:

#include <type_traits>
#include <iostream>

template<typename T> using is_ref = std::enable_if_t<std::is_reference_v<T>, bool>;
template<typename T> using is_not_ref = std::enable_if_t<!std::is_reference_v<T>, bool>;

template<typename T, is_ref<T> = true>
void foo(T&&) {
    std::cout << "ref" << std::endl;
}

template<typename T, is_not_ref<T> = true>
void foo(T&&) {
    std::cout << "not ref" << std::endl;
}

int main() {
    int a = 0;
    foo(a);
    foo(5);
}

而这个不起作用:

#include <type_traits>
#include <iostream>

template<typename T> using is_ref = std::enable_if_t<std::is_reference_v<T>, bool>;
template<typename T> using is_not_ref = std::enable_if_t<!std::is_reference_v<T>, bool>;

template<typename T, typename = is_ref<T>>
void foo(T&&) {
    std::cout << "ref" << std::endl;
}

template<typename T, typename = is_not_ref<T>>
void foo(T&&) {
    std::cout << "not ref" << std::endl;
}

int main() {
    int a = 0;
    foo(a);
    foo(5);
}

typename = is_ref&lt;T&gt;is_ref&lt;T&gt; = true 之间的真正区别是什么?

【问题讨论】:

    标签: c++ c++14 c++17 sfinae template-function


    【解决方案1】:

    如果您删除默认模板参数,就会清楚区别是什么。函数声明不能​​在只是它们的默认值上有所不同。这是格式错误的:

    void foo(int i = 4);
    void foo(int i = 5);
    

    同样这是不正确的:

    template <typename T=int> void foo();
    template <typename T=double> void foo();
    

    考虑到这一点,您的第一个案例:

    template<typename T, is_ref<T>>
    void foo(T&&);
    
    template<typename T, is_not_ref<T>>
    void foo(T&&);
    

    这里的两个声明是唯一的,因为两个声明的第二个模板参数不同。第一个具有类型为std::enable_if_t&lt;std::is_reference_v&lt;T&gt;, bool&gt; 的非类型模板参数,第二个具有类型为std::enable_if_t&lt;!std::is_reference_v&lt;T&gt;, bool&gt; 的非类型模板参数。这些是不同的类型。

    然而,你的第二种情况:

    template<typename T, typename>
    void foo(T&&);
    
    template<typename T, typename>
    void foo(T&&)
    

    这显然是相同的签名 - 但我们只是复制了它。这是格式错误的。


    另见cppreference's explanation

    【讨论】:

    • 绝对合乎逻辑...您建议使用哪个最明确?在所有情况下都使用typename =,当你需要时使用另一种。或者每次都使用enable_if&lt;bool&gt; =
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多