C++ 修复用非标量类型实例化模板时的编译错误
但是,如果我取消注释最后一行,我会得到:C++ 修复用非标量类型实例化模板时的编译错误,c++,c++11,templates,C++,C++11,Templates,但是,如果我取消注释最后一行,我会得到: int: 2147483647 short: 32767 float: 0 x.cpp:int get\u max\u if\u integral()[带T=S]的实例化中: x、 cpp:22:40:从这里开始需要 x、 cpp:11:82:错误:从类型“S”到类型“int”的强制转换无效 if(std::is_integral::value)返回(int)std::numeric_limits::max(); 在这种情况下,我希望函数返回0。我建
int: 2147483647
short: 32767
float: 0
x.cpp:int get\u max\u if\u integral()[带T=S]的实例化中:
x、 cpp:22:40:从这里开始需要
x、 cpp:11:82:错误:从类型“S”到类型“int”的强制转换无效
if(std::is_integral::value)返回(int)std::numeric_limits::max();
在这种情况下,我希望函数返回
0
。我建议您将函数拆分为两个不同的函数,并启用SFINAE
x.cpp: In instantiation of ‘int get_max_if_integral() [with T = S]’:
x.cpp:22:40: required from here
x.cpp:11:82: error: invalid cast from type ‘S’ to type ‘int’
if ( std::is_integral<T>::value ) return (int) std::numeric_limits<T>::max();
模板
typename std::enable_if::type
如果积分()
{return(int)std::numeric_limits::max();}
模板
typename std::enable_if::type
如果积分()
{返回0;}
可以完成这项工作,但这是c++17。@BlackMoses:太棒了!澄清一下,因为答案没有解释:错误是因为使用常规if
;由于当T
为S
时,(int)std::numeric\u limits::max()
无效,因此编译器会抱怨,即使它永远不会执行。对于SFINAE,每个分支都是一个不同的函数。使用constexpr if,编译前会丢弃false
分支,有效地使其与内联SFINAE一样工作。在这两种情况下,这意味着它永远不会看到(int)std::numeric\u limits::max()
。(注意One()
与Two()
完全相同,One()
与Two()
完全相同)
x.cpp: In instantiation of ‘int get_max_if_integral() [with T = S]’:
x.cpp:22:40: required from here
x.cpp:11:82: error: invalid cast from type ‘S’ to type ‘int’
if ( std::is_integral<T>::value ) return (int) std::numeric_limits<T>::max();
template <typename T>
typename std::enable_if<true == std::is_integral<T>::value, int>::type
get_max_if_integral ()
{ return (int) std::numeric_limits<T>::max(); }
template <typename T>
typename std::enable_if<false == std::is_integral<T>::value, int>::type
get_max_if_integral ()
{ return 0; }