【发布时间】:2021-01-16 20:14:17
【问题描述】:
假设我有以下课程:
class Extra final
{
public:
void Method1() const {std::cout << "Method 1" << std::endl;}
void Method2() const {std::cout << "Method 2" << std::endl;}
};
我为某些类T创建了一个类模板,可以根据不同的场景在编译时启用/禁用使用Extra的方法(在枚举中列出):
enum class Scenario
{
None, // No extra.
One, // Only Method1 allowed.
Two, // Only Method2 allowed.
Both // Both Method1 and Method2 allowed.
};
类模板如下:
template<typename T, Scenario R>
class ExtraAdder : public T
{
};
template<typename T>
class ExtraAdder<T, Scenario::One> : public T
{
public:
void Method1Extra() const {m_extra.Method1();}
private:
Extra m_extra;
};
template<typename T>
class ExtraAdder<T, Scenario::Two> : public T
{
public:
void Method2Extra() const {m_extra.Method2();}
private:
Extra m_extra;
};
template<typename T>
class ExtraAdder<T, Scenario::Both> : public T
{
public:
void Method1Extra() const {m_extra.Method1();}
void Method2Extra() const {m_extra.Method2();}
private:
Extra m_extra;
};
可以这样使用:
class Base
{
public:
virtual ~Base() = default;
void BaseMethod() const {std::cout << "Base method" << std::endl;}
// Some other stuff...
};
int main(int argc, char **argv)
{
std::cout << "Scenario: None" << std::endl;
ExtraAdder<Base, Scenario::None> none;
none.BaseMethod();
//none.Method1Extra(); // Does not compile.
//none.Method2Extra(); // Does not compile.
std::cout << std::endl << "Scenario: One" << std::endl;
ExtraAdder<Base, Scenario::One> one;
one.BaseMethod();
one.Method1Extra();
//one.Method2Extra(); // Does not compile.
std::cout << std::endl << "Scenario: Two" << std::endl;
ExtraAdder<Base, Scenario::Two> two;
two.BaseMethod();
//two.Method1Extra(); // Does not compile.
two.Method2Extra();
std::cout << std::endl << "Scenario: Both" << std::endl;
ExtraAdder<Base, Scenario::Both> both;
both.BaseMethod();
both.Method1Extra();
both.Method2Extra();
return 0;
}
关键是通过更改模板参数Scenario,我只能访问包装的m_extra 成员的某些方法,这正是我想要的。但是,如您所见,不同的专业非常冗长(并且有一些重复)。
问题:有没有一种方法可以生成完全相同的模板特化,但以一种不那么冗长的方式,有限制或没有重复?
我发现最接近解决此问题的是this question(使用std::enable_if),但我无法根据我的情况调整它。
我正在使用带有 C++17 标准的 g++。
【问题讨论】:
-
添加的方法之间是否没有共享公共状态(即
class Extra在您的实际代码中为空)?
标签: c++ templates template-specialization