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

时间:2015-11-26 02:16:24

标签: c++ c-preprocessor

我有一个类似下面的模板类。它应该使用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() is not executed by preprocessor和朋友)。

但是,在预处理器运行之前很久就保存了源代码,并且uint32_tuint64_t的大小永远不会改变,因此所有这些信息都可以在编译的每个阶段获得处理。我只是不知道如何访问它。

1 个答案:

答案 0 :(得分:6)

预处理器对模板,模板参数或类型一无所知。那是一个死胡同。

也许标签调度会使你的分析工具闭嘴。

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