假设,我有一个代码:
template <typename T>
class C {
public:
T f() { return m_result; }
void todo() { m_result = doit<T>(); }
private:
T m_result;
};
如果T
是void
,我想返回void
并且根本没有m_result
。
但是,编译器不允许实例化 void
类型。
其中一项决定是创建特化。
template <> class C<void> { /* ... */ }
但我不支持几乎相同的代码。
我怎样才能不实例化m_result
?
我可以使用 C++17。谢谢!
最佳答案
您可以将数据放在基类中,然后使用 if constexpr
:
template<class T>
struct C_data{
T m_result;
};
template<>
struct C_data<void>{
};
template<class T>
class C: C_data<T>
{
static constexpr auto is_void = std::is_same_v<T,void>;
public:
auto f(){
if constexpr(is_void)
return this->m_result;
else
return;
}
void todo(){
if constexpr(is_void)
this->m_result = doit<T>();
else
doit<T>();
}
};
但是可以说 C 类的特化更清晰,因为模板类的所有成员都应该依赖于所有模板参数(否则你应该拆分你的类以避免代码膨胀)。
所以我更愿意完全专门化 C,并使 C 类的一部分独立于 T,成为 C 的基类:
class C_base{
//any thing that is independent of T;
};
template<class T>
class C: public C_base{
//any thing that depend on T
};
template<>
class C<void>: public C_base{
//any thing that depend on T;
};
您也可以按成员函数专门化成员函数,但我发现它不太干净。
您会在几乎所有标准库实现的头文件中找到最后一个代码结构。
关于c++ - 条件编译和模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48297727/