比较 sizeof(type) == constant 时,C++ 模板特化不起作用

标签 c++ templates c++11

#include <cstdint>
#include <iostream>

uint32_t ReadInt() { return 0; }
uint64_t ReadLong() { return 0; }

template<class SizeType>
class MyType
{
  public:
    SizeType Field;
    MyType()
    {
        Field = sizeof(SizeType) == 8 ? ReadLong() : ReadInt();
    }
};

int main()
{
    MyType<uint32_t> m;
    std::cout << m.Field;
}

我收到编译器警告,因为它看起来像条件​​ sizeof(MyType) == 4 在编译时未被评估。

如果是这样的话,我们就会有特化,这就不是问题了。

无论如何我都能做到这一点?

编辑:我真正想要实现的是:

        Field = ReadLong();

        Field = ReadInt();

通过模板元编程。我可以在不专门化 Read* 函数的情况下执行此操作吗?考虑到 C++ 模板的强大功能,我真的觉得我错过了一些惊喜时刻,因为如果我必须专门化 Read* 函数,兔子洞会继续变得更深。

最佳答案

warning C4244: '=': conversion from 'int64_t' to 'uint32_t', possible loss of data for the int specialization 

I get a compiler warning because it looks like the the condition sizeof(MyType) == 4 is not being evaluated at compile time.

不,它看起来根本不像那样。是否在编译时评估比较对条件表达式的返回类型没有影响。

如果我们通过删除条件并使用您使用的类型扩展模板来简化示例,我们将得到这个最小复制:

uint32_t Field;
int64_t temp = ReadInt(); // temporary variable for exposition
Field = temp;

显然,int64_t 可能包含一个比 int32_t 所能表示的值大得多的值。如果是这样,那么正确的值将在转换中丢失。编译器会警告这种可能性。


您可能会问为什么条件 int64_t 的类型特别明确。嗯,每个子表达式的类型分别是 int64_tuint32_t,所以类型必须是其中之一。 Field 的类型或比较结果 - 即使在编译时评估 - 对选择哪种类型没有影响。相反,integral promotion在这种情况下使用规则。


Anyway I could achieve this?

模板函数应该可以工作:

template<class T>
T Read() {
    static_assert(false, "not implemented");
}

template<>
uint64_t Read<uint64_t>() {
    return ReadLong();
}

template<>
uint32_t Read<uint32_t>() {
    return ReadInt();
}

// ...
Field = Read<SizeType>();

关于比较 sizeof(type) == constant 时,C++ 模板特化不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39679740/

相关文章:

c++ - 使用带有模板参数的模板函数作为模板类时出错

c++ - 获取模板实例化的类型?

c++ - std::less<int> 的正确参数类型是什么?

c++ - 为什么即使 T 的 value_type 是 const,std::is_const::value 也是 'false'?

c++ - DirectX 汽车与世界一起前进

c++ - 通过 (char* bar) 和 (char are[ ]) 传递 char 数组是否相同? C++

c++ - 我可以使用动态数组作为 C++ 模板类型名吗?

C++在派生类中调用基类的模板方法

c++ - std::is_base_of 用于模板类

c++ - 带有 std::vector 和带有缩减的标量变量的 OpenMP for 循环