首先,代码
vector<T> kvec;
for (ulong kv = 0; kv < ke.count; kv++)
{
T key;
if (typeid(T) != typeid(QUAT32))
{
fread(&key, sizeof(T), 1, fh);
}
else{
shortQuat key16;
fread(&key16, sizeof(shortQuat), 1, fh);
key.Parse(key16);
}
kvec.push_back(key);
}
在 key.Parse(key16);
处抛出以下编译器错误:
error C2039: 'Parse' : is not a member of 'libm2::VEC3F'
当然不是;但问题是任何具有 VEC3F 类型的东西都不应该到达那里。显然,编译器使用的是第一种类型,它被发送到该片段所属的类,这很好——但为什么要忽略条件呢?
是的,如果我注释掉那一行,它编译得很好——并且条件在运行时工作得很好。
所以我想真正的问题是,处理这个问题的最佳方法是什么,而不必为一种特殊类型复制整个类?
最佳答案
扩展我的评论:
if
在运行时运行,而不是编译时(优化器可能会删除分支,但它必须首先进行编译才能做到这一点)。
您可以改用模板特化,是在编译时完成的(编译器在编译之前为您提供的每种类型实例化模板函数的单独拷贝).您可以提供专门化以针对特定类型强制使用不同(特殊)的函数体,这正是您在这种情况下想要的。
这是从您问题中的代码派生的示例(我假设非 QUAT32 的双推回 kvec
是错字):
template<typename T>
inline void readKey(T& key, FILE* fh)
{
fread(&key, sizeof(T), 1, fh);
}
template<>
inline void readKey<QUAT32>(QUAT32& key, FILE* fh)
{
shortQuat key16;
fread(&key16, sizeof(shortQuat), 1, fh);
key.Parse(key16);
}
// ...
vector<T> kvec;
for (ulong kv = 0; kv < ke.count; kv++)
{
T key;
readKey(key, fh);
kvec.push_back(key);
}
关于c++ - 为什么编译器似乎忽略了模板类中的 if 语句?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23820208/