我为enum设计了一个带有模板专门化的结构体,像这样:
template<DataType type>
struct TypeTrait;
template<>
struct TypeTrait<DATA_TYPE_INT8> {
static constexpr uint32_t size = sizeof(int8_t);
};
template<>
struct TypeTrait<DATA_TYPE_INT16> {
static constexpr uint32_t size = sizeof(int16_t);
};
template<>
struct TypeTrait<DATA_TYPE_FP16> {
static constexpr uint32_t size = sizeof(uint16_t);
};
template<>
struct TypeTrait<DATA_TYPE_UINT8> {
static constexpr uint32_t size = sizeof(uint8_t);
};
template<>
struct TypeTrait<DATA_TYPE_UINT16> {
static constexpr uint32_t size = sizeof(uint16_t);
};
template<>
struct TypeTrait<DATA_TYPE_INT32> {
static constexpr uint32_t size = sizeof(int32_t);
};
template<>
struct TypeTrait<DATA_TYPE_UINT32> {
static constexpr uint32_t size = sizeof(uint32_t);
};
template<>
struct TypeTrait<DATA_TYPE_FP32> {
static constexpr uint32_t size = sizeof(float);
};
字符串
enum DataType是这样定义的:
enum DataType {
DATA_TYPE_INT8 = 0,
DATA_TYPE_INT16 = 1,
DATA_TYPE_FP16 = 2,
DATA_TYPE_UINT8 = 3,
DATA_TYPE_UINT16 = 4,
DATA_TYPE_INT32 = 5,
DATA_TYPE_UINT32 = 6,
DATA_TYPE_FP32 = 7,
DATA_TYPE_UNKOWN
};
型
我想传递一个DataType变量给结构体TypeTrait,像这样:
class Test {
public:
...
void Convert() {
...
uint32_t size = TypeTrait<type_>::size;
...
}
private:
DataType type_;
};
型
当我这样做时,编译程序时会出现问题:
main.cc: In member function ‘void Test::Convert()’:
main.cc:63:35: error: use of ‘this’ in a constant expression
63 | uint32_t size = TypeTrait<type_>::size;
| ^~~~~
main.cc:63:40: error: use of ‘this’ in a constant expression
63 | uint32_t size = TypeTrait<type_>::size;
| ^
main.cc:63:35: note: in template argument for type ‘DataType’
63 | uint32_t size = TypeTrait<type_>::size;
| ^~~~~ ^
型
我尝试了很多方法,比如将type_
转换为const值,如下所示:
const DataType dataType = type_;
uint32_t size = TypeTrait<dataType>::size;
型
然后这个问题出现了。
main.cc: In member function ‘void Test::Convert()’:
main.cc:63:39: error: the value of ‘type’ is not usable in a constant expression
63 | uint32_t size = TypeTrait<type>::size;
| ^
main.cc:62:24: note: ‘type’ was not initialized with a constant expression
62 | const DataType type = GetType();
| ^~~~
main.cc:63:39: note: in template argument for type ‘DataType’
63 | uint32_t size = TypeTrait<type>::size;
|
型
我知道如果我像这样传递枚举元素,程序将不会有问题。
uint32_t size = TypeTrait<DataType::DATA_TYPE_UINT32>::size;
型
我没有办法解决这个问题。所以我必须使用switch case来处理这个问题,这是违背我的意愿的。我只是想在我的代码中删除switch case。要重构的代码:
switch (dataType_) {
case DATA_TYPE_INT8:
byteSize = elemCnt * sizeof(int8_t);
break;
case DATA_TYPE_INT16:
byteSize = elemCnt * sizeof(int16_t);
break;
case DATA_TYPE_FP16:
byteSize = elemCnt * sizeof(uint16_t);
break;
case DATA_TYPE_UINT8:
byteSize = elemCnt * sizeof(uint8_t);
break;
case DATA_TYPE_UINT16:
byteSize = elemCnt * sizeof(uint16_t);
break;
case DATA_TYPE_INT32:
byteSize = elemCnt * sizeof(int32_t);
break;
case DATA_TYPE_UINT32:
byteSize = elemCnt * sizeof(uint32_t);
break;
case DATA_TYPE_FP32:
byteSize = elemCnt * sizeof(float);
break;
}
型
2条答案
按热度按时间rjjhvcjd1#
下面是一种在运行时获取
TypeTrait<type>::size
的方法,而无需开关(需要C++17):字符串
Demo
另一个,使用
std::array
(来自Jarod 42的评论- C++17):型
eaf3rand2#
在不使用模板专门化的情况下添加另一个答案。
我认为这种实现方式更加方便和简洁
字符串