c++ - 根据用户输入创建特定类型的对象

标签 c++ templates c++11 variadic

我们有

enum Enum {A,B,C,D,E,F,G,H, NumEnums};

class Base {};

template <Enum...> class Thing : public Base {};

和函数

Base* create (std::list<Enum>& input);

是创建input对应类型的对象.例如, 如果input = {A,E,C,G,D}; , 那么输出的类型应该是 Thing<A,E,C,G,D>* (让我们忘记这里的排序)。现在我知道input是在运行时获得的,但是通过搜索,可以相当快地获得输出。如果Thing只有一个参数(即 input 有一个 size()),那么简单

template <int N>
Base* createHelper (const std::list<Enum>& input) {
    const Enum En = static_cast<Enum>(N);
    if (input.front() == En)
        return new Thing<En>;
    return createHelper<N+1>(input);
}

template <>
Base* createHelper<NumEnums> (const std::list<Enum>&) {
    return nullptr;
}

Base* create (const std::list<Enum>& input) {
    return createHelper<0>(input);
}

会做。我试图将上面的内容概括为任何大小的列表(大小必须在运行时通过与上面类似的递归来确定,但这也应该相当快)。但我完全迷失了如何。所以我尝试检查 naïve 方法的结构:

#include <iostream>
#include <list>
#include <type_traits>
#include <typeinfo>

enum Enum {A,B,C,D,E,F,G,H, NumEnums};

class Base {
    public:
        virtual void print() const = 0;
};

template <Enum...> class Thing : public Base {
    virtual void print() const override {std::cout << typeid(*this).name() << '\n';}
};

Base* create (std::list<Enum>& input) {
    if (input.front() == A) {
        input.pop_front();
        if (input.empty())
            return new Thing<A>;
        else {
            if (input.front() == A) {
                input.pop_front();
                if (input.empty())
                    return new Thing<A,A>;
                else {
                    // ....
                }
            }
            else if (input.front() == B) {
                input.pop_front();
                if (input.empty())
                    return new Thing<A,B>;
                else {
                    // ....
                }
            }               
        }
    }
    else if (input.front() == B) {
        // similar
    }
    // ...
}

int main() {
    std::list<Enum> userInput = {A,B};
    // Wish to construct an instance of Thing<A,B> (efficiently).
    Base* thing = create(userInput);
    thing->print();  // Thing<A,B>
}

我想我可以把它写成递归形式。但我想不出来。我知道一维情况可以推广,但我在这里需要帮助。或者也许有更好的方法来完成它?一旦它开始工作,create 的时间应该不会超过几分之一秒。函数返回,假设 NumEnums大小适中,Thing类只有几个模板参数,而不是数百个。

最佳答案

编辑: 事实证明,可能有一个可行的解决方案 here :

  1. 在您的键和类型工厂类之间创建一个关联数组。

  2. 选择类型工厂后,动态分配您可能需要的任何变量(最好使用 std::unique_ptr)。

最终的结果可能是这样的:

std::unordered_map<std::string, type_allocator> str_to_type;
str_to_type["a"] = type_allocator(int); //where type_allocator derives the type of the class from the input variable.
auto variable = str_to_type[input].allocate();

关于c++ - 根据用户输入创建特定类型的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31888305/

相关文章:

c# - Encoding.utf8 将逗号转换为 C# 中的某些特殊字符

c++ - 根据 C++ 中的数据类型设置默认值

c++ - 通过在每个元素上调用 name() 将 Class 的 vector 转换为 decltype(Class::name()) 的 vector

c++ - 对 `gnuplot_init()' 的 undefined reference

c++ - 复合文字并通过GCC在C++中通过引用传递?

c++ - 位数的数据类型大小

c++ - 模板友元函数和返回类型推导

c++ - 为什么这个模板不能编译?

c++ - 调用模板化基类的模板化成员失败

javascript - C++ - 实现 JS 的 setTimeout 的现代方法