Why does the compiler seem to ignore if statements in templated classes?

前端 未结 3 899
别那么骄傲
别那么骄傲 2021-01-16 22:14

First off, the code

vector kvec;

for (ulong kv = 0; kv < ke.count; kv++)
{
    T key;
    if (typeid(T) != typeid(QUAT32))
    {


        fread         


        
相关标签:
3条回答
  • 2021-01-16 22:42

    Another solution is to declare static variable in the template class, that stores previously defined type ID and check it when need to.

    #define CNTYPE_NONE     0
    #define CNTYPE_STRING   1
    #define CNTYPE_SIGNINT  2
    
    template <typename key_t, typename value_t>
    class HashTable 
    {
    public:
        HashTable() {;}
        ...................
        static int m_nTypeID;
        // and later you can check the type by:    
    
        void SomeFunc()
        {
            if(m_nTypeID == CNTYPE_STRING) 
            {
                ................
            } 
            else 
            {
                ................
            }
        }
    };
    
    typedef HashTable<std::string, std::string> THashTableString;
    typedef HashTable<int, int> THashTableSignInt;
    
    THashTableString::m_nTypeID = CNTYPE_STRING;
    THashTableSignInt::m_nTypeID = CNTYPE_SIGNINT;
    
    int main()
    {
        THashTableString strTable;
        THashTableSignInt intTable;
        .........................................        
    
        return 0;
    }
    
    0 讨论(0)
  • 2021-01-16 22:49

    To expand on my comment:

    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.

    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);
    }
    
    0 讨论(0)
  • 2021-01-16 23:06

    Problem: Needed to handle a special case in a templated constructor, that needed to be converted for usefulness. But, as I feared, if statements are ignored on compile.

    Solution:

    Add a second type to the template, and create a type-cast operator in one of the types.

    vector<T> kvec;
    for (ulong kv = 0; kv < ke.count; kv++)
    {
        T2 key;
        fread(&key, sizeof(T2), 1, fh);
        kvec.push_back((T)key);
    }
    

    In most cases, the class would be constructed like so:

    SomeClass c = SomeClass<typeA,typeA>(fh);
    

    obviously, casting between the same type should be pretty straightforward. But in the case of QUAT32...

    SomeClass c = SomeClass<QUAT32,SHORT_QUAT>(fh);
    

    the solution was to just do this:

    typedef struct SHORT_QUAT
    {
        short x;
        short y;
        short z;
        short w;
        operator const QUAT32(){
            QUAT32 q;
            q.x = float(x < 0 ? x + 32768 : x - 32767) / 32767.0f;
            q.y = float(y < 0 ? y + 32768 : y - 32767) / 32767.0f;
            q.z = float(z < 0 ? z + 32768 : z - 32767) / 32767.0f;
            q.w = float(w < 0 ? w + 32768 : w - 32767) / 32767.0f;
            return q;
        }
    }shortQuat;
    

    and then the data that was stored in shortquat form could be cast to the more useful float format without issue.

    It just seemed like a waste to have to create an entire duplicate just for a special case. I'd like to think it's the lesser of two ugly.

    0 讨论(0)
提交回复
热议问题