如何在C++中区分模板类型

How to distinguish a Template Type in C++

本文关键字:类型 中区 C++      更新时间:2023-10-16

我有一个模板类,我想写一个成员方法,它能够识别模板被实例化为什么类型。

我需要创建一个包含以下类型信息的字符串标识符:

  • 钻头深度
  • 有符号或无符号
  • 浮点或int或char

该方法应该返回以以下方式组成的字符串:

字符串:(BIT_DEPTH)-(U|S)-(C|I|F)

BIT_DEPTH->是用于表示类型的位数

U|S->描述类型是有符号的还是无符号的

C|I|F->描述类型是char int还是浮点

我想到了一种找到比特深度的方法:

int bitDepth = sizeof(TemplateType) * 8;

可以吗?

但是不知道如何找到我需要的其他信息,除非像下面这样的switch-case语句是可以的(但不要这么认为):

THE FOLLOWING IS PSEUDO CODE THAT YOU SHOULD HELP ME EXPRESS IN A CORRECT SYNTAX
switch(TemplateType){
    case signed: ...;
    case unsigned: ...;
    default: ...;
}

我的问题有两个:

  • 钻头深度计算正确吗
  • switch-case语句是个好主意吗?(如果是,请纠正语法)

比特计算可以,但可以通过使用CHAR_BIT而不是8来改进,请参阅此问题。

要获得其他信息,您可以使用<type_traits>,特别是:

  • std::is_signed/std::is_unsigned
  • std::is_integral/std::is_floating_point

请注意,浮点类型总是有符号的,但std::is_signed将返回false,因为它测试该类型是否是有符号的整数

还要注意,char只是另一个积分类型,因此没有标准的类型特征来专门测试这一点,但您可以使用简单的std::is_same<T, char>

在代码中,这可能看起来如下:

#include <iostream>
#include <type_traits>
#include <climits> // CHAR_BIT
template<class T>
void f(){
  std::cout << sizeof(T) * CHAR_BIT << "-";
  if(std::is_integral<T>::value){
     if(std::is_signed<T>::value)
       std::cout << "S";
     else
       std::cout << "U";
     std::cout << "-";
     if(std::is_same<T, char>::value)
       std::cout << "C";
     else
       std::cout << "I";
  }else if(std::is_floating_point<T>::value){
    std::cout << "S-F";
  }
  std::cout << "n";
}

Ideone上的实例。

注意,bool计数为无符号整数,但这很容易修复。还要注意的是,编译器会发出一堆关于"条件表达式是常量"的警告,因此可以进行改进,但这应该足以作为一个演示。

要添加到Xeo的答案中,您可以在编译时使用std::enable_if来删除这些警告。例如:

template<typename T>
inline
typename std::enable_if<std::is_signed<T>::value, char>::type
sign() { return 'S'; }
template<typename T>
inline
typename std::enable_if<std::is_unsigned<T>::value, char>::type
sign() { return 'U'; }

不过,需要注意的一点是,floatis_signed就是false