假设我有这个课:

class Component1;
class Component2;
// many different Components
class Component42;

class MyClass
{
public:
    MyClass(void) {};
    std::list<Component1> component1List;
    std::list<Component2> component2List;
    // one list by component
    std::list<Component42> component42List;
};

我想创建一个具有以下签名的函数:
template<class T> void addElement(T component);

它应该执行以下操作:
  • 如果componentComponent1类型,则将其添加到Component1List
  • 如果component的类型为Component2,请将其添加到Component2List等。

  • 是否可以?有什么好方法吗?

    我可以通过类似的功能获得相同的行为:
    template<class T> void addElement(int componentType, T component);
    

    但是我宁愿不必像这样指定componentType:它是无用的信息,并且为可能的错误打开了大门(如果componentType不代表组件的类型)。

    最佳答案

    std::tuple进行救援。
    更新日志:

  • 使用std::decay_t
  • 添加了可变参数形式
  • add_component()现在返回对此的引用以允许调用链接。
  • #include <iostream>
    #include <list>
    #include <utility>
    #include <type_traits>
    #include <tuple>
    
    class Component1 {};
    class Component2 {};
    struct Component3 {
        Component3() {}
    };
    // many different Components
    
    template<class...ComponentTypes>
    class MyClassImpl
    {
        template<class Component> using list_of = std::list<Component>;
    
    public:
    
        using all_lists_type =
        std::tuple<
        list_of<ComponentTypes> ...
        >;
    
    
        // add a single component
        template<class Component>
        MyClassImpl& add_component(Component&& c)
        {
            list_for<Component>().push_back(std::forward<Component>(c));
            return *this;
        }
    
        // add any number of components
        template<class...Components>
        MyClassImpl& add_components(Components&&... c)
        {
            using expand = int[];
            void(expand { 0, (void(add_component(std::forward<Components>(c))), 0)... });
            return *this;
        }
    
    
    
        template<class Component>
        auto& list_for()
        {
            using component_type = std::decay_t<Component>;
            return std::get<list_of<component_type>>(_lists);
        }
    
        template<class Component>
        const auto& list_for() const
        {
            using component_type = std::decay_t<Component>;
            return std::get<list_of<component_type>>(_lists);
        }
    
    
    private:
    
        all_lists_type _lists;
    };
    
    using MyClass = MyClassImpl<Component1, Component2, Component3>;
    
    int main()
    {
        MyClass c;
    
        c.add_component(Component1());
        c.add_component(Component2());
    
        const Component3 c3;
        c.add_component(c3);
    
        c.add_components(Component1(),
                         Component2(),
                         Component3()).add_components(Component3()).add_components(Component1(),
                                                                                   Component2());
    
        std::cout << c.list_for<Component1>().size() << std::endl;
    
        return 0;
    }
    

    关于c++ - C++模板: one list by class,如何分解代码?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34587245/

    10-10 13:33