为什么编译器似乎忽略模板类中的if语句? [英] Why does the compiler seem to ignore if statements in templated classes?

查看:117
本文介绍了为什么编译器似乎忽略模板类中的if语句?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,代码

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);处引发以下编译器错误:

the following compiler error is thrown at key.Parse(key16); :

error C2039: 'Parse' : is not a member of 'libm2::VEC3F'

当然不是;但是问题在于,任何带有VEC3F类型的产品都不应该到达那里.显然,编译器使用的是第一种类型,该类型被发送到snippet所在的类,这很好-但是为什么要忽略条件式呢?

Of course it doesn't; but the problem is that anything with the type of VEC3F shouldn't even get there. Obviously the compiler is using the first type that gets sent to the class that snippet is from, which is fine - but why ignore the conditional?

是的,如果我对此进行注释,它可以很好地编译-并且条件运行时可以正常工作.

And yeah, if I comment that line out, it compiles fine - and the conditional works fine at runtime.

所以我想真正的问题是,无需为一个特殊类型重复整个类的最佳方法是什么?

So I guess the real question is, what's the best way to deal with this, without having to duplicate an entire class for one specialized type?

推荐答案

展开我的评论:

if在运行时运行,而不是在编译时运行(优化器可能会删除该分支,但必须首先进行编译才能达到目的).

The if runs at runtime, not compile time (the optimizer might remove the branch, but it has to compile in the first place to get that far).

您可以改用模板专用化,模板专用化是在编译时完成的(对于编译器,您为之前为其指定的每种类型实例化模板化函数的单独副本. ).您可以提供一种特殊化,以对特定类型强制使用不同的(特殊)函数体,在这种情况下,这正是您想要的.

You can use template specialization instead, which is done at compile time (the compiler instantiates a separate copy of the templated function for each type you give it before compiling it). You can provide a specialization to force a different (special) function body for particular types, which is exactly what you want in this case.

这是一个从您问题中的代码派生的示例(我假设非QUAT32的对kvec的double-push_back是一个错字):

Here's an example derived from the code in your question (I'm assuming the double-push_back to kvec for non QUAT32s is a typo):

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);
}

这篇关于为什么编译器似乎忽略模板类中的if语句?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆