gpt4 book ai didi

c++ - 根据一些枚举值在编译时添加额外的方法

转载 作者:行者123 更新时间:2023-12-03 10:05:03 25 4
gpt4 key购买 nike

想象一下我有以下类(class):

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++与C++ 17标准一起使用。

最佳答案

或者,您可以将enable_if放入模板中,而不是返回类型声明中。我个人觉得这更具可读性,它的优点是可以使用返回类型推导。

template<typename T, Scenario R>
class ExtraAdder : public T {
Extra m_extra;
public:
template<
Scenario S = R,
typename = std::enable_if_t<(S == Scenario::One || S == Scenario::Both)>
>
void Method1Extra() const {
m_extra.Method1();
}


template<
Scenario S = R,
typename = std::enable_if_t<(S == Scenario::Two || S == Scenario::Both)>
>
decltype(auto) Method2Extra() const {
return m_extra.Method2();
}

};
实时示例 here
enable_if与成员函数一起使用的常见陷阱是,仅当模板参数的替换格式不正确时,它才有效。因此,我们需要添加额外的模板参数 Scenario S = R(或其他答案中的 bool),以便将替换操作推迟到使用该方法的地方。否则,将不会有这样的替换导致硬错误。请参阅 this question进行更深入的讨论。

关于c++ - 根据一些枚举值在编译时添加额外的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65754250/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com