SFINAE works differently in cases of type and non-type template parameters(SFINAE 在类型和非类型模板参数的情况下工作方式不同)
问题描述
为什么这段代码有效:
template<
typename T,
std::enable_if_t<std::is_same<T, int>::value, T>* = nullptr>
void Add(T) {}
template<
typename T,
std::enable_if_t<!std::is_same<T, int>::value, T>* = nullptr>
void Add(T) {}
并且可以正确区分这两个调用:
and can correctly distinguish between these two calls:
Add(1);
Add(1.0);
而以下代码如果编译会导致重新定义 Add() 错误?
while the following code if compiled results in the redefinition of Add() error?
template<
typename T,
typename = typename std::enable_if<std::is_same<T, int>::value, T>::type>
void Add(T) {}
template<
typename T,
typename = typename std::enable_if<!std::is_same<T, int>::value, T>::type>
void Add(T) {}
所以如果模板参数是类型的,那么我们重新定义了函数,如果是非类型的,那么一切正常.
So if the template parameter is type, then we have redefinition of the function, if it is non-type, then everything is ok.
推荐答案
SFINAE 是关于替代的.所以让我们代替!
SFINAE is about substitution. So let us substitute!
template<
typename T,
std::enable_if_t<std::is_same<T, int>::value, T>* = nullptr>
void Add(T) {}
template<
typename T,
std::enable_if_t<!std::is_same<T, int>::value, T>* = nullptr>
void Add(T) {}
变成:
template<
class T=int,
int* = nullptr>
void Add(int) {}
template<
class T=int,
Substitution failure* = nullptr>
void Add(int) {
template<
class T=double,
Substitution failure* = nullptr>
void Add(double) {}
template<
class T=double
double* = nullptr>
void Add(double) {}
删除我们得到的失败:
template<
class T=int,
int* = nullptr>
void Add(int) {}
template<
class T=double
double* = nullptr>
void Add(double) {}
现在删除模板参数值:
template<
class T,
int*>
void Add(T) {}
template<
class T
double*>
void Add(T) {}
这些是不同的模板.
现在搞砸了:
template<
typename T,
typename = typename std::enable_if<std::is_same<T, int>::value, T>::type>
void Add(T) {}
template<
typename T,
typename = typename std::enable_if<!std::is_same<T, int>::value, T>::type>
void Add(T) {}
变成:
template<
typename T=int,
typename =int>
void Add(int) {}
template<
typename int,
typename = Substitution failure >
void Add(int) {}
template<
typename T=double,
typename = Substitution failure >
void Add(double) {}
template<
typename T=double,
typename = double>
void Add(double) {}
删除失败:
template<
typename T=int,
typename =int>
void Add(int) {}
template<
typename T=double,
typename = double>
void Add(double) {}
现在模板参数值:
template<
typename T,
typename>
void Add(T) {}
template<
typename T,
typename>
void Add(T) {}
这些是相同的模板签名.这是不允许的,会产生错误.
These are the same template signature. And that is not allowed, error generated.
为什么会有这样的规定?超出了这个答案的范围.我只是在演示这两种情况的不同之处,并断言标准对它们的处理方式不同.
Why is there such a rule? Beyond the scope of this answer. I'm simply demonstrating how the two cases are different, and asserting that the standard treats them differently.
当您使用上述非类型模板参数时,您更改模板签名而不仅仅是模板参数值.当您使用上述类型模板参数时,您只需更改模板参数值.
When you use a non-type template parameter like the above, you change the template signature not just the template parameter values. When you use a type template parameter like the above, you only change the template parameter values.
这篇关于SFINAE 在类型和非类型模板参数的情况下工作方式不同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:SFINAE 在类型和非类型模板参数的情况下工作方式
基础教程推荐
- C++结构和函数声明。为什么它不能编译? 2022-11-07
- 如何检查GTK+3.0中的小部件类型? 2022-11-30
- 如何在 C++ 中初始化静态常量成员? 2022-01-01
- 如何将 std::pair 的排序 std::list 转换为 std::map 2022-01-01
- 我有静态或动态 boost 库吗? 2021-01-01
- 这个宏可以转换成函数吗? 2022-01-01
- 常量变量在标题中不起作用 2021-01-01
- 静态库、静态链接动态库和动态链接动态库的 .lib 文件里面是什么? 2021-01-01
- 如何通过C程序打开命令提示符Cmd 2022-12-09
- 在 C++ 中计算滚动/移动平均值 2021-01-01
