c – SFINAE:删除具有相同原型的函数

我想知道这个代码有什么区别:
#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>,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< T>之间的真正区别是什么?和is_ref< T> =真的吗?

解决方法

如果删除认模板参数,则会清楚区别的是什么.函数声明只能在认值上有所不同.这是不正确的:
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< std :: is_reference_v< T>,bool>第二个是非类型模板参数,其类型为std :: enable_if_t<!std :: is_reference_v< T>,bool>.那些是不同的类型.

然而,你的第二个案例:

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

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

这显然是相同的签名 – 但我们只是重复它.这是不正确的.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...