假设,我有一个代码:
template <typename T>
class C {
public:
T f() { return m_result; }
void todo() { m_result = doit<T>(); }
private:
T m_result;
};
Run Code Online (Sandbox Code Playgroud)
如果T是void,我想回来void,一点也不m_result.
但是,编译器不允许实例化void类型.
其中一个决定是创建专业化.
template <> class C<void> { /* ... */ }
Run Code Online (Sandbox Code Playgroud)
但我不支持几乎完全相同的代码.
我怎么不实例化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>();
}
};
Run Code Online (Sandbox Code Playgroud)
但可以说 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;
};
Run Code Online (Sandbox Code Playgroud)
您还可以按成员函数专门化成员函数,但我发现它不太干净。
您将在几乎所有标准库实现的标头中找到最后一个代码结构。