我有一个模板类,并希望编写一个能够识别模板实例化类型的成员方法。
我需要创建一个字符串标识符,其中包含类型的以下信息:
该方法应返回以下列方式组成的字符串:
string:(BIT_DEPTH) - (U | S) - (C | I | F)
BIT_DEPTH - >是用于表示类型
的位数U | S - >描述类型是签名还是未签名
C |我| F - >描述type是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
声明是个好主意吗? (如果是,请纠正语法)答案 0 :(得分:7)
位计算没问题,但可以使用CHAR_BIT
代替8
进行改进,请参阅this question。
要获取其他信息,您可以使用<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";
}
请注意,bool
计为无符号整数,但很容易修复。另请注意,编译器会发出一系列关于“条件表达式是常量”的警告,因此可以改进,但这应该足以作为演示了。
答案 1 :(得分:2)
要添加到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'; }
但要注意的一件事是is_signed
的{{1}}是float
!