SFINAE:删除具有相同原型的函数 [英] SFINAE : Delete a function with the same prototype

查看:115
本文介绍了SFINAE:删除具有相同原型的函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I wonder what is the difference between this code that works :

#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<T>is_ref<T> = true之间的真正区别是什么?

What is the true difference between typename = is_ref<T> and is_ref<T> = true ?

推荐答案

如果删除默认的模板参数,将会清楚有什么区别.函数声明的默认值不能只是.这是错误的格式:

If you remove the default template arguments, it'll become clear what the difference is. Function declarations cannot differ in just their defaults. This is ill-formed:

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

同样,这是错误的形式:

And likewise this is ill-formed:

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


请记住,您的第一种情况:


With that in mind, your first case:

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>的非类型模板参数.这些是不同的类型.

The two declarations here are unique because the second template parameter differs between the two declarations. The first has a non-type template parameter whose type is std::enable_if_t<std::is_reference_v<T>, bool> and the second has a non-type template parameter whose type is std::enable_if_t<!std::is_reference_v<T>, bool>. Those are different types.

第二种情况:

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

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

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

This is clearly the same signature - but we've just duplicated it. This is ill-formed.

另请参见 cppreference的解释.

这篇关于SFINAE:删除具有相同原型的函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆