c++ - 为什么编译器似乎忽略了模板类中的 if 语句?

标签 c++ visual-studio

首先,代码

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/

相关文章:

c# - 在 C# 中部署控制台应用程序的方法

c++ - 在没有内存复制的情况下左修剪 std::vector

java - 类型安全的编程语言..?

c++ - 在 Windows 上查找文件的 MIME 类型

c++ - 使用 swig 使 C++ 类看起来像一个 numpy 数组

visual-studio - 为什么编译按钮在 Visual Studio 中被禁用?

visual-studio - Visual Studio 2017 "Go to All"未列出项目

c# - 项目已过时 - 不再显示此对话框 - 构建还是不构建?

visual-studio - 为什么我的 MSBuild 文件中需要一个单独的项目?

c++ - 有没有办法包含 std::filesystem 的转发 header ?