如何在带有模板参数的预处理器中使用sizeof

How to use sizeof in preprocessor with a template parameter?

本文关键字:处理器 预处理 sizeof 参数      更新时间:2023-10-16

我有一个模板类,如下所示。它意味着用32位字或64位字来实例化。

foo.h

template <typename WORD>
class Foo
{
public:
    ...
    void Init();
    ...
private:
    WORD* m_ptr;
};

foo.cpp

template <typename WORD>
void Foo<WORD>::Init()
{
#if (sizeof(WORD) == 8)
    // Do something
#elif (sizeof(WORD) == 4)
    // Do something else
#endif
}

编译它会导致GCC下的error: missing binary operator before token "(";和Clang下的token is not a valid binary operator in a preprocessor subexpression

我不想提供单独的专业化,因为这正是代码模板的初衷。我还相信它将打破我们对基类指针和引用(在派生类中)所做的一些事情。

如何访问模板参数WORD的大小并使用它来选择代码路径?


以下内容会很好,但它会产生警告,我正试图压制。例如,它在Coverity:下生成result_independent_of_operands

WORD unused;
if (sizeof(unused))
{
    ...
}

我还了解到预处理器在编译器之前运行。我对此没有误解(例如,sizeof()不是由预处理器和朋友执行的)。

但是,早在预处理器运行之前,源代码就已经保存了,而且uint32_tuint64_t的大小从未改变,因此所有这些信息在编译过程的每个阶段都是可用的。我只是不知道如何访问它。

预处理器对模板、模板参数或类型一无所知。这是一条死胡同。

也许标记调度会使您的分析工具关闭。

template <typename WORD>
class Foo
{
public:
    void Init();
private:
    WORD* m_ptr;
    template<std::size_t> struct size_tag {};
    void Init_impl(size_tag<8>) { /* Do something */ }
    void Init_impl(size_tag<4>) { /* Do something else */ }
};
template <typename WORD>
void Foo<WORD>::Init()
{
    Init_impl(size_tag<sizeof(WORD)>());
}