两种模板代码模式之间的区别,一种情况下分配了一个数字,而另一种情况下使用关键字 typename
Difference between two template code patterns where in one case a number is assigned whereas in the other the keyword typename is used
在下面的代码中,下面两行模板有什么区别。
> 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>>
以上两行都工作正常,我只是想知道 advantages/disadvantage 在使用其中一条时优于另一条。
#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);
}
如果你只写一个函数,它们都工作正常。
但是当你想要两个替代函数时,这样
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,即替换失败不是错误。
重点是换人。
第一种方式,当你调用
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; }
因为第二个函数中的替换失败导致该函数无法使用并被丢弃。所以你只有一个功能可用,没有碰撞。
在下面的代码中,下面两行模板有什么区别。
> 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>>
以上两行都工作正常,我只是想知道 advantages/disadvantage 在使用其中一条时优于另一条。
#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);
}
如果你只写一个函数,它们都工作正常。
但是当你想要两个替代函数时,这样
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,即替换失败不是错误。
重点是换人。
第一种方式,当你调用
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; }
因为第二个函数中的替换失败导致该函数无法使用并被丢弃。所以你只有一个功能可用,没有碰撞。