我有一个类似下面的模板类。它应该使用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_t
和uint64_t
的大小永远不会改变,因此所有这些信息都可以在编译的每个阶段获得处理。我只是不知道如何访问它。
答案 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)>());
}