C++ 我如何使用类型作为“变量”?

C++ 我如何使用类型作为“变量”?,c++,C++,[对象、实体或香蕉的类型]是我想象中的变量类型。 我想做的是传递一个类,例如,然后使用CreateObj函数创建该类型的新对象并使用它。 我该怎么做呢?简短回答:不 长答覆: 你有像std::type_index和typeid这样的工具,但它们不能满足你的需要 但是,您可以存储工厂函数而不是类型: #include <iostream> #include <string> #include <vector> #include <map> std:

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

简短回答:不

长答覆:

你有像std::type_index和typeid这样的工具,但它们不能满足你的需要

但是,您可以存储工厂函数而不是类型:

#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();
}
存储在映射中的函数创建已知类型的实例。由于映射必须存储相同类型的函数,因此必须通过公共类型返回。该公共类型可以是std::any、std::variant或指向基类的指针

然后,您可以在映射中搜索factory函数并调用它以获得创建的对象。它必须正确地展开才能通过正确的类型访问变量以访问成员。

简短回答:否

长答覆:

你有像std::type_index和typeid这样的工具,但它们不能满足你的需要

但是,您可以存储工厂函数而不是类型:

#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();
}
存储在映射中的函数创建已知类型的实例。由于映射必须存储相同类型的函数,因此必须通过公共类型返回。该公共类型可以是std::any、std::variant或指向基类的指针


然后,您可以在映射中搜索factory函数并调用它以获得创建的对象。必须正确地展开它,才能通过访问成员的正确类型访问变量。

如果不想使用多态性,可以通过元编程执行以下操作:

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);
然后,构造对象:

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>{}();
}

这会增加编译时间,但在运行时不会降低性能。

如果不想使用多态性,可以使用元编程:

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);
然后,构造对象:

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>{}();
}

这会增加编译时间,但在运行时不会有任何性能损失。

IMHO,如果您试图动态创建对象,静态factory设计模式将是合适的。为了类型安全,您可以将类型表示为枚举类,而不是字符串。您可以使用std::variant,它是为这些情况设计的。IMHO,如果您试图动态创建对象,静态工厂设计模式将是合适的。为了类型安全,您可以将类型表示为枚举类,而不是字符串。您可以使用std::variant,它是为这些情况设计的。