使用专门的模板并命名枚举选项

Use specialized template and name the enum option

我通过枚举专门化了一个模板

template<>
class specialized_class<user_option=CHOICE_ENUM::CHOSEN_OPTION>
{

public:

    typedef second_class<user_option> obj_type;

在这里,要定义second_class,我需要知道用户选择了什么类型。我需要命名所选的选项。但是我的代码的第二行是非法语法。如何做我需要的?

虽然

    typedef second_class<CHOICE_ENUM::CHOSEN_OPTION> obj_type;

解决问题。我宁愿避免这种方式,因为它使用的是魔术类型,并且 class 中的代码需要修改才能在其他地方使用。

如果您正在尝试减少 CHOICE_ENUM::CHOSEN_OPTION 在专业化中的出现。也许以下就足够了。

enum Enum
{
    E1,
    E2
};

template<Enum E>
class Foo
{
};

template<Enum E>
class Bar
{
};

template<>
class Foo<E2> // 1 occurrence to change if copy/pasted for a new specialization
{
public:
    static const Enum enum_value = E2; // Last occurrence to change

    typedef Bar<enum_value> obj_type;
};

您可以使用部分专业化和一些 sfinae,但解决方案最终会有点 wtf-factor。 Here's 一个演示。

首先,更改主模板

template<CHOICE_ENUM e, typename Enable = void>
class specialized_class;

默认参数允许您继续使用 specialized_class 之前使用它的方式 - 您仍然可以假装它是一个单参数 class 模板。现在,将您的全特化转换为部分特化 + sfinae:

template <CHOICE_ENUM user_option>
class specialized_class<user_option,
      std::enable_if_t<user_option == CHOICE_ENUM::CHOSEN_OPTION>>
{
  //stuff
};

从这个简短的例子中有点难以分辨,但您可以将专业化的通用部分分解为基础 class 以避免参数重复。

template<CHOICE_ENUM option>
struct user_option_base {
    static const CHOICE_ENUM user_option = option;
};

template<>
class specialized_class<CHOICE_ENUM::CHOSEN_OPTION>
    : user_option_base<CHOICE_ENUM::CHOSEN_OPTION>
{
public:
    typedef second_class<specialized_class::user_option> obj_type;

要避免限定 specialized_class::user_option,您可以使用 using user_option_base::user_option;