类似枚举的派生类

Enum-like derived class

本文关键字:派生 枚举      更新时间:2023-10-16

我目前有一个代码如下:

enum class Mode {
Foo,
Bar
};
void function(int a, Mode mode);

我想大幅扩展"模式"。特别是,我想允许一个接受Option类和几个enum(类似(对象之一的选项参数。这样,用户可以执行以下任一操作:

function(a, Mode::Foo);
function(a, Direction::Forward);
function(a, Option(...)); 

这在function的单个过载下可能吗?但是,这样function只接受一个Option对象并Mode::FooMode::BarDirection::ForwardDirection::Backward(并且不超过这个,使用通用模板,因为它会破坏我的重载分辨率(。


我的想法是让类派生自Option,并拥有

void function(int a, const Option& option);

但是我不知道如何在用户不需要为ModeDirection添加括号的情况下执行此操作:

function(a, Mode::Foo());
function(a, Direction::Forward());
function(a, Option(...)); 

我不想保持向后兼容性。

您可以使用简单的对象作为标志,尽管您将失去enum的一些优势(即使您也可以解决此问题(:

struct Option{};
struct Mode
{
Mode Foo;
}

将此行放在C++文件中,它应该只在一个翻译单元中

Mode Mode::Foo{};

然后你可以使用简单的重载:

void function(const Option& opt);

当然,您可以放置私有/受保护的构造函数,以防止在类定义之外创建其他对象。

另一种解决方案是使用模板,带有 SFINAE 或 C++20 约束/概念来限制您允许作为参数的内容。