函数模板参数推导模板参数 vs 默认模板参数 vs 返回类型

问题描述

这是一个关于当模板参数用作模板参数 vs 作为默认模板参数 vs 作为返回类型时模板推导如何工作的问题。

1:普通模板参数

如使用 GCC 和 VS 编译测试,以下代码片段未能推导出由 std::enable_if_t 定义的模板参数

#include <iostream>
#include <type_traits>

template< class T,std::enable_if_t< std::is_integral_v< T > > >
void SwapInPlace( T& left,T& right )
{
   left = left ^ right;
   right = left ^ right;
   left = left ^ right;
} 

template< class T,std::enable_if_t< std::is_floating_point_v< T > > >
void SwapInPlace( T& left,T& right )
{
    left = left - right;
    right = left + right;
    left = right - left;
}

int main()
{   
   int i1 = 10;
   int i2 = -120;
   std::cout << i1 << " " << i2 << std::endl;
   SwapInPlace( i1,i2 );
   std::cout << i1 << " " << i2 << std::endl;

   double d1 = 1.1234;
   double d2 = 2.5678;  
   std::cout << d1 << " " << d2 << std::endl;
   SwapInPlace( d1,d2 );
   std::cout << d1 << " " << d2 << std::endl;

   return 0;
}

VS: 错误 C2783: 'void SwapInPlace(T &,T &)': 无法推断 '__formal' 的模板参数

GCC:无法推导出模板参数 -anonymous-

2:默认模板参数

将第二个模板参数声明为默认模板参数可以使推导正常工作:

template< class T,class = std::enable_if_t< std::is_integral_v< T > > >
void SwapInPlace( T& left,T& right )
{...}

template< class T,class = std::enable_if_t< std::is_floating_point_v< T > >,bool = true >
void SwapInPlace( T& left,T& right )
{...}

bool = true 添加到第二次重载只是为了避免编译错误,因为不可能基于默认模板参数重载函数模板。只想关注演绎在这里可以正常工作的事实。如果只有一个模板使用默认参数,例如对于 std::is_integral,只要我们将正确的参数传递给它,它就会编译并正常工作。

3:返回类型

在返回类型的情况下,一切都可以编译并运行良好:

template< class T >
std::enable_if_t < std::is_integral_v< T > >
SwapInPlace( T& left,T& right )
{...}

template< class T >
std::enable_if_t < std::is_floating_point_v< T > >
SwapInPlace( T& left,T& right )
{...}

4:具有默认值的模板参数

另一种编译此代码的方法是为 std::enable_if 定义的模板参数添加默认值。在最后一个右尖括号之前添加了 * = nullptr,因此如果 std::enable_if 条件评估为 true,那么我们的第二个参数变为 void*,默认值为 nullptr

template< class T,std::enable_if_t< std::is_integral_v< T > >* = nullptr >
void SwapInPlace( T& left,std::enable_if_t< std::is_floating_point_v< T > >* = nullptr >
void SwapInPlace( T& left,T& right )
{...}

所以问题是:在这 4 种情况下如何演绎:为什么它在第一种情况下失败而在其他三种情况下成功?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)