首页 > 解决方案 > 在 C++ 中使用参数包作为类属性是否可能和/或良好做法?

问题描述

我正在编写一个简单的模板结构(在 C++ 中),它可以在控制台中显示一个格式化的“菜单”。我这样做主要是为了玩可变参数。该结构的模板通过自动推导输入类型 ( InputTy)、提示类型 ( PromptTy,通常可能是 astd::stringconst char*) 和消息的参数包 ( class... MsgTypes) 来工作。该类的声明如下所示:

template<class InputTy, class PrompTy, class... MsgTypes>
struct Menu 
{
    // ... Stuff in here ... //
};

我想对这个类做的是将它保存MsgTypes为一种“可变类属性”。本质上,这看起来像:

template<class InputTy, class PromptTy, class... MsgTypes>
struct Menu
{
public:
    Menu(PromptTy prompt_text, MsgTypes... menu_text) : prompt_text(prompt_text),
        menu_text(menu_text) {}

    // Displays the formatted menu (uses variadic attribute)
    inline void display() 
    {
        display_recurse(menu_text);
        std::cout << std::endl << prompt_text;
        std::cin >> input_var; std::cin.ignore(10000, '\n');
        /* ... Etc ... */
    }

protected:
    InputTy input_var;
    PromptTy prompt_text;
    MsgTypes... menu_text;  // Variadic attribute

    // Recursive function for displaying the text of a menu
    template<typename Ty, typename... Types>
    inline void display_recurse(Ty cur_line, Types next_lines)
    {
        std::cout << cur_line << std::endl;
        display_recurse(next_lines);
    }

    // No-arg function overload for recursive generic function with parameter pack
    inline void display_recurse() {}
};

标签: c++ooptemplatesvariadic-templatesgeneric-programming

解决方案


是否有可能......在 C++ 中使用参数包作为类属性?

不完全的。参数包只能扩展为参数列表、表达式或初始化器,但不能扩展为声明。

有一个标准模板std::tuple,它基本上可以实现您可能想要做的事情。它是一个模板类,每个可变参数类型参数作为成员对象。因此,在您的情况下,您可能有一个成员:

std::tuple<MsgTypes...> menu_text;

如果您想知道,元组本身是如何实现这一点的:您可以将一个模板参数作为非包,将其作为成员并使用其余参数包递归地继承模板的另一个实例。


推荐阅读