C++类名数组

标签 c++ g++ metaprogramming template-meta-programming

我正在构建一个可以通过添加新类来扩展的 c++ 框架

我想找到一种方法来简化新类的扩展。

我当前的代码如下:

class Base {
public:
    virtual void doxxx() {...}
};

class X: public Base {
public:
    static bool isMe(int i) { return i == 1; }
};

class Y: public Base {
public:
    static bool isMe(int i) { return i == 2; }
};

class Factory {
public:
    static std::unique_ptr<Base> getObject(int i) {
        if (X::isMe(i)) return std::make_unique<X>();
        if (Y::isMe(i)) return std::make_unique<Y>();

        throw ....
    }
};

还必须为每个新类添加一个新的 if 语句。

现在我想找到一种方法来重写我的工厂类(使用元编程),可以通过调用 add 方法来添加新类 工厂类看起来像下面的伪代码:

class Factory
{
public:
    static std::unique_ptr<Base> getObject(int i) {
        for X in classNames:
            if (X::isMe(i)) return std::make_unique<X>();

        throw ....
    }

    static void add() {...}

    static classNames[];...
};

Factory::add(X);
Factory::add(Y);

. .

这样的事情可能吗? 非常感谢

最佳答案

您可能会执行以下操作:

template <typename ... Ts>
class Factory {
public:
    static std::unique_ptr<Base> createObject(int i) {
        if (i < sizeof...(Ts)) {
            static const std::function<std::unique_ptr<Base>()> fs[] = {
                [](){ return std::make_unique<Ts>();}...
            };
            return fs[i]();
        }
        throw std::runtime_error("Invalid arg");
    }

};

用法是:

using MyFactory = Factory<X, Y /*, ...*/>;

auto x = MyFactory::createObject(0);
auto y = MyFactory::createObject(1);

如果你想要运行时注册,你可以这样做:

class Factory {
public:
    static std::unique_ptr<Base> createObject(int i) {
        auto it = builders.find(i);
        if (it == builders.end()) {
            throw std::runtime_error("Invalid arg");
        }
        return it->second();
    }

template <typename T>
void Register()
{
    builders.emplace(T::Id, [](){ return std::make_unique<T>();});
}

private:
    std::map<int, std::function<std::unique_ptr<Base>()>> builders;
};

用法是:

class X: public Base {
public:
    static constexpr int id = 1;
};

class Y: public Base {
public:
    static constexpr int id = 2;
};

Factory factory;
factory.register<X>();
factory.register<Y>();

auto x = factory.createObject(1);
auto y = factory.createObject(Y::id);

关于C++类名数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48926376/

相关文章:

c++ - 具有一个显式参数的模板

c++ - 双向链表,tail 的问题

c++ - g++ L"string~"+ 运算符,类似于 Visual C++

c++ - 如何链接 netbeans (linux) 中的库?

c++ - 与某些库链接时无法捕获异常

Ruby 捕获 NoMethodError 并从发生异常的地方继续执行

c++ - 带有附加变量的 Glfw 回调

c++ - 如果我们关闭主应用程序,以 QProcess 启动的进程不会退出

c++ - 仅当它不是模板时才编译具有结构类型的同名变量

c++ - 捕获数组模板参数的大小