首页 > 解决方案 > C++:在子类中扩展静态 STL 容器/映射成员?

问题描述

目前我的代码看起来很像

#include <map>
#include <string>
#include <functional>

void SomeFunc();
void SomeOtherFunc();

struct Calls {
    std::string name;
    std::function<void(void)> a, b;
};

struct BaseClass
{
    static const std::map<std::string, Calls> callbacks; 
    const std::map<std::string, Calls>* pCallbacks = &callbacks; // Run-time polymorphism, pointers are *typically* upcast back to base class.
};
const std::map<std::string, Calls> BaseClass::callbacks = {{"testX", {"x", SomeFunc, SomeOtherFunc}}};

void MoreFuncs();
void MoreFuncs2();

struct DerivedClass : BaseClass
{
    static const std::map<std::string, Calls> callbacks;
    const std::map<std::string, Calls>* pCallbacks = &callbacks;
};
const std::map<std::string, Calls> DerivedClass::callbacks = {
                {"testX", {"x", SomeFunc, SomeOtherFunc}},
                {"testY", {"g", MoreFuncs, MoreFuncs2}}};

struct DeepClass : DerivedClass
{
    static const std::map<std::string, Calls> callbacks;
    const std::map<std::string, Calls>* pCallbacks = &callbacks;
};
const std::map<std::string, Calls> DeepClass::callbacks = {
                {"testX", {"x", SomeFunc, SomeOtherFunc}},
                {"testY", {"g", MoreFuncs, MoreFuncs2}},
                {"testZ", {"h", SomeOtherFunc, MoreFuncs2}},
};

在更大的体积。以这种方式扩展很累,在我看来会留下太多的视觉集群。有什么技术可以让这更容易吗?

标签: c++oopinheritancestl

解决方案


你可以写一个像

auto concat_maps(std::map<std::string, Calls> first, const std::map<std::string, Calls>& second)
{
    first.insert(second.begin(), second.end());
    return first;
}

它将一张地图合并到另一张地图中。这允许您将派生类映射定义为父类映射和要添加的元素的串联。那看起来像

struct DerivedClass : BaseClass
{
    static const std::map<std::string, Calls> callbacks;
    const std::map<std::string, Calls>* pCallbacks = &callbacks;
};
const std::map<std::string, Calls> DerivedClass::callbacks = 
      concat_maps( BaseClass::callbacks, {{"testY", {"g", MoreFuncs, MoreFuncs2}}});

struct DeepClass : DerivedClass
{
    static const std::map<std::string, Calls> callbacks;
    const std::map<std::string, Calls>* pCallbacks = &callbacks;
};
const std::map<std::string, Calls> DeepClass::callbacks = 
      concat_maps( DerivedClass::callbacks, {{"testZ", {"h", SomeOtherFunc, MoreFuncs2}}});

推荐阅读