我如何将类型用作“变量”?

时间:2019-04-06 21:07:41

标签: c++

#include <iostream>
#include <string>
#include <vector>
#include <map>

std::vector<std::pair<std::string, [type of the object, entity or banana]>> nep; //[type of the object, entity or banana] is my imaginary type

class Entity
{
private:
    int x;
public:
    Entity(const int x) : x(x) {};
    int GetX() const { return x; };
};

class Banana
{
private:
    int y;
public:
    Banana(const int y) : y(y) {};
    int GetY() const { return y; };
};

[type of the object, entity or banana] CreateObj(std::string name) //Used that imaginary variable here again
{
    for (unsigned short int i = 0; i < nep.size(); i++)
    {
        if (nep.at(i).first == name)
        {
            return [new object with type = nep.at(i).second];
        }
    }
}

int main()
{
    nep.push_back({ "ent", Entity });
    nep.push_back({ "banan", Banana });

    CreateObj(banan).GetY();

    std::cin.get();
}

[对象,实体或香蕉的类型]是我想象中的变量类型的东西。 我想做的是例如在那里传递一个类,然后使用CreateObj()函数创建该类型的新对象并使用它。 我该怎么办?

2 个答案:

答案 0 :(得分:2)

简短的回答:否

长答案:

您拥有std::type_indextypeid之类的工具,但它们无法满足您的需求。

但是,您可以存储工厂功能而不是类型:

using result = std::any; // or some other common type

std::map<std::string, std::function<std::any()>> nep;

nep["banana"] = []{ return Banana{}; };
nep["entity"] = []{ return Entity{}; };

// Call the functions:
result my_banana = nep["banana"]();
Banana& b = std::any_cast<Banana&>(my_banana);

存储在映射中的函数创建已知类型的实例。由于映射必须存储相同类型的函数,因此必须通过通用类型返回它。该常见类型可以是std::anystd::variant<Banana, Entity>或指向基类的指针。

然后,您可以在地图上搜索工厂函数,然后调用它以获取创建的对象。必须正确解开它才能通过访问成员的正确类型访问变量。

答案 1 :(得分:1)

如果您不想使用多态性,则可以使用元编程来做一些事情:

enum class ClassType {
    EntityType,    
    BananaType,
};

namespace internal {

    template <ClassType Type>
    struct _build_type {};

    template <>
    struct _build_type<ClassType::EntityType> {
        constexpr auto operator()() {
            return EntityType();
        }
    };

    template <>
    struct _build_type<ClassType::BananaType> {
        constexpr auto operator()() {
            return BananaType();
        }
    };
} 

然后,您的构造对象:

template <ClassType Type>
constexpr auto create_instance() {
    return internal::_build_type<Type>{}();
}

因此您可以这样做:

const auto object = create_instance<BananaType>();

这件事会增加您的编译时间,但在运行时不会造成任何性能损失。

相关问题