好了,我有一个用C语言编写的库,可以读取文件并提供对其数据的访问。数据是类型化的,因此我使用的是空指针和一些访问器函数:
typedef struct nbt_tag
{
nbt_type type; /* Type of the value */
char *name; /* tag name */
void *value; /* value to be casted to the corresponding type */
} nbt_tag;
int64_t *nbt_cast_long(nbt_tag *t)
{
if (t->type != TAG_LONG) return NULL;
return (int64_t *)t->value;
}
对于不同的类型(内置:TAG_BYTE(
char
),TAG_SHORT(int16_t
),TAG_INT(int32_t
),TAG_LONG(int64_t
),TAG_FLOAT(float
),TAG_DOUBLE(double
数据类型)和TAG ,TAG_List(char *
),TAG_COMPOUND(struct nbt_list
),TAG_BYTE_ARRAY(struct nbt_compound
)。我现在正试图以一种优雅的方式将其映射到C++,但我无法完成...
char getByte(); // TAG_BYTE
int16_t getShort(); // TAG_SHORT
int32_t getInt(); // TAG_INT
int64_t getLong(); // TAG_LONG
float getFloat(); // TAG_FLOAT
double getDouble(); // TAG_DOUBLE
std::string getString(); // TAG_STRING
std::vector<char> getByteArray(); // TAG_BYTE_ARRAY
std::vector<Tag> getCompound(); // TAG_COMPOUND
这感觉太冗长了..还有更好的方法吗?
最佳答案
这可以完成工作:
template <int> struct TypeTag {};
template <> struct TypeTag<TAG_BYTE> { typedef char type; };
// ...
template <> struct TypeTag<TAG_COMPOUND> { typedef vector<Tag> type; };
template <int tag>
typename TypeTag<tag>::type getValue(nbt_tab* t)
{
if (t->type != tag) ... // throw an exception
return *reinterpret_cast<typename TypeTag<tag>::type*>(t-value);
}
并像这样使用它:
char x = getValue<TAG_BYTE>(t);
vector<Tag> v = getValue<TAG_COMPOUND>(t);
您可能想要添加特化内容,例如
template <>
vector<Tag> getValue<TAG_COMPOUND>(nbt_tab* t)
{
if (t->type != TAG_COMPOUND) ... // throw something
vector<Tag> ans(/* size */); // [rely on named return value optimization]
// Fill the vector with your data
return ans; // [Pray for the copy constructor not to get called]
}
关于c++ - 包装此空指针的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3742405/