动态实例化一个名称存储在字符串中的结构 - C ++

问题描述 投票:-1回答:2

我有一个字符串变量,其中包含结构的名称。此结构在头文件中声明。我想基于结构名称的值创建一个结构的对象,该结构名称保存在C ++的字符串变量中。

struct myStruct{
    int a;
    char b;
};

string structName = "myStruct";
// Instantiate a structure variable [like this: "struct myStruct"]

有人可以帮我这个吗?

c++ structure
2个回答
5
投票

您正在寻找的功能称为。这是C ++没有的东西。所以你应该按顺序回退:

  1. 质疑你的设计
  2. 写一个黑客

这是一个黑客的想法:

using result_type = /* some type, possibly void */;
std::unique_ptr<result_type> factory(std::string const& kind)
{
    if (kind == "alice") return new alice;
    if (kind == "bob")   return new bob;
    // ...
    return nullptr;
}

0
投票

在C ++中,无法通过在运行时确定的名称创建类的实例。 C ++对reflect的能力很弱。

但是,您可以自己构建支持。这里的想法是为工厂函数创建一个name-string映射,该函数返回该类型的实例。返回的实例需要包含在std::any中,因为C ++ - 作为强类和静态类型的语言 - 不能让返回类型在运行时确定。

有一个函数add_factory,必须为您希望能够使用该名称实例化的所有类型调用它。还有一个辅助宏,它像所有宏一样,因魔法而起作用。

auto& factories() {
    static std::unordered_map<std::string, std::any(*)()> factories;
    return factories;
}

template<class T>
void
add_factory(const char* name) {
    // further development: take function as argument so that
    // non-default-constructible classes can be supported
    factories()[name] = []() -> std::any {
        return T{};
    };
}

std::any
create(const char* name)
{
    const auto& f = factories();
    if (f.find(name) != f.end())
        return f.find(name)->second();
    throw std::runtime_error("I haven't heard of this type");
}

// don't use this macro in header files
#define ADD_FACTORY(name) namespace { auto dummy_##name = (add_factory<name>(#name), 0); }

// ----- usage -----

struct a {
    int i;
};
ADD_FACTORY(a)

struct b {
    double d;
};
ADD_FACTORY(b)

// factories are not limited to classes
ADD_FACTORY(int)


int main()
{
    std::any instance = create("a");
    assert(std::any_cast<a>(&instance));
}
© www.soinside.com 2019 - 2024. All rights reserved.