Динамически создавать структуру, имя которой хранится в строке - C ++ - PullRequest
0 голосов
/ 12 сентября 2018

У меня есть строковая переменная, которая содержит название структуры.Эта структура объявлена ​​в заголовочном файле.Я хотел бы создать объект структуры на основе значения имени структуры, которое содержится в строковой переменной в C ++.

struct myStruct{
    int a;
    char b;
};

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

Может кто-нибудь помочь мне с этим?

Ответы [ 2 ]

0 голосов
/ 12 сентября 2018

Невозможно в C ++ создать экземпляр класса по имени, определенному во время выполнения. C ++ обладает очень малой способностью отражать .

Однако вы могли бы создать поддержку для него самостоятельно. Идея в том, чтобы создать карту 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));
}
0 голосов
/ 12 сентября 2018

Функция, которую вы ищете, называется . Это то, что 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...