Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 基于“的部分模板专门化”;签名“ness”;整数类型?_C++_Templates_Specialization_C++17 - Fatal编程技术网

C++ 基于“的部分模板专门化”;签名“ness”;整数类型?

C++ 基于“的部分模板专门化”;签名“ness”;整数类型?,c++,templates,specialization,c++17,C++,Templates,Specialization,C++17,鉴于: 当T是无符号类型时,有没有聪明的方法不进行比较n>=0?我尝试添加部分模板专门化: unsigned n; f( n ); // warning: comparison n >= 0 is always true 模板 内联布尔f(无符号T n){ 返回n可以利用无符号整数的环绕行为 template<typename T> inline bool f( unsigned T n ) { return n <= 100; } 您可以为无符号类型实现特

鉴于:

T
无符号类型时,有没有聪明的方法不进行比较
n>=0
?我尝试添加部分模板专门化:

unsigned n;
f( n ); // warning: comparison n >= 0 is always true
模板
内联布尔f(无符号T n){

返回n可以利用无符号整数的环绕行为

template<typename T>
inline bool f( unsigned T n ) {
  return n <= 100;
}   

您可以为
无符号
类型实现特殊的模板函数实现,如:

template<typename T>
inline bool f( T n ) {
  return (n == 0 || n > 0) && n <= 100;
}   

如果
带有
无符号
类型特征,则可以使用
启用:

template <class T, bool U> bool f(T val)
{
        if (U)
                return val <= 100;
        else
                return (val >=0 ) && (val <= 100);
}

...

cout << f<int, false>(1) << endl;
cout << f<int, false>(-1) << endl;
cout << f<char, true>(10) << endl;
模板
typename std::enable_if::type f(tn)
{
返回n::类型f(tn)
{
返回n>=0&&n
当T是无符号类型时,有没有聪明的方法不进行比较n>=0?我尝试添加了部分模板专门化:

unsigned n;
f( n ); // warning: comparison n >= 0 is always true
优化器应该删除比较的代码,因为它检测到了条件

对于叮当声,添加
-Wno同义反复比较
以消除警告。对于GCC/G++,添加
-Wno类型限制
以消除警告

如果您使用的编译器支持
pragma诊断{push | pop}
,您可以:

#if(GCC_版本>=40600)|(LLVM_CLANG_版本>=10700)|(APPLE_CLANG_版本>=20000)
#定义GCC\u诊断\u可用1
#恩迪夫
#如果MSC_版本
#pragma警告(推送)
#杂注警告(禁用:4389)
#恩迪夫
#如果GCC\u诊断\u可用
#pragma GCC诊断推送
#已忽略pragma GCC诊断“-Wsign compare”
#如果(LLVM_-CLANG_版本>=20800)| |(APPLE_-CLANG_版本>=30000)
#已忽略pragma GCC诊断“-Wtautological compare”
#elif(GCC\U版本>=40300)
#pragma GCC诊断已忽略“-W类型限制”
#恩迪夫
#恩迪夫
模板
内联布尔函数f(tn){
return n>=0&&n从介绍开始,您甚至不需要为此提供专门化。与正常的if语句不同,如果表达式不为true,
if constexpr
中的代码将被丢弃(未编译)。这意味着您可以像

template <typename T>
typename std::enable_if<std::is_unsigned<T>::value, bool>::type f(T n)
{
    return n <= 100;  
}

template <typename T>
typename std::enable_if<!std::is_unsigned<T>::value, bool>::type f(T n)
{
    return n >= 0 && n <= 100;  
}
模板
内联布尔函数f(tn)
{
如果constexpr(std::is_unsigned_v)

返回n=0&&n,但它必须适用于所有无符号类型:char、short、int、long。与其他利用“enable_if”(或类似功能)的解决方案相比,您的解决方案要详细得多。您的解决方案似乎也是唯一一个可以在C++03中实现而不使用boost的解决方案。这在我的书中是一个明显的优点。我将在它开始工作时进行投票;)请注意,函数模板没有部分专门化,只有完全专门化。也就是说,完全专门化通常对函数模板是一个坏主意,因为关于什么被专门化,什么被重载,以及重载解析如何决定使用什么的规则是复杂而复杂的。谢天谢地,重载和SFINAE(替换失败不是错误)在这里就足够了。我从Clang 3.8(或GCC 8.0)中没有得到任何警告在这方面。如果我在
f
上删除模板,我会得到它。是否有考虑模板实例化的
-Wtautological compare
版本?
如果constepr
是伟大的模板编程简化器。为什么它只适用于返回类型,而不适用于参数(这是关于它的,并且会发现它更符合逻辑),比如:
template bool(typename std::enable_if::type n)
template <class T, bool U> bool f(T val)
{
        if (U)
                return val <= 100;
        else
                return (val >=0 ) && (val <= 100);
}

...

cout << f<int, false>(1) << endl;
cout << f<int, false>(-1) << endl;
cout << f<char, true>(10) << endl;
template <typename T>
typename std::enable_if<std::is_unsigned<T>::value, bool>::type f(T n)
{
    return n <= 100;  
}

template <typename T>
typename std::enable_if<!std::is_unsigned<T>::value, bool>::type f(T n)
{
    return n >= 0 && n <= 100;  
}
template<typename T>
inline bool f( T n ) 
{
    if constexpr (std::is_unsigned_v<T>)
        return n <= 100;
    else
        return n >= 0 && n <= 100;
}