Как динамически собрать список типов для передачи в качестве параметра шаблона переменной - PullRequest
0 голосов
/ 21 июня 2019

У меня есть функция, которая принимает параметр шаблона переменной в качестве входных данных. Что мне действительно нужно сделать, так это использовать какой-то магический контейнер (список типов, кортеж и т. Д.) Для подачи этого параметра функции. Основная проблема заключается в том, что этот магический контейнер необходимо динамически собирать во время выполнения на основе входных данных для предыдущих вызовов функций.

Стандартное генерирование кортежей, очевидно, не может работать в этой среде, поэтому я считаю, что нужен какой-то тип оболочки или помощника с некоторым искажением имен, но способ сделать это ускользает от меня. Ниже приведен пример псевдокода того, что я пытаюсь сделать. Пользователь будет вызывать AddComponent() любое количество раз, чтобы добавить ряд компонентов в менеджер-владелец. Для каждого экземпляра AddComponent() мне нужно сохранить переданный тип «Компонент» в магический контейнер, чтобы в итоге я получил контейнер со всеми добавленными типами Компонентов. После всего этого мне нужно вызвать GetView(), используя собранный список названий типов в качестве параметра для шаблона переменной. Здесь лучше всего подходит кортеж, но как правильно его собрать? Вот код:

template<typename Component, typename ... Args>
void Blueprint::AddComponent(ComponentUsage usage, Args&& ... args)
{
// Create component object with given args

// Add 'Component' type to magic container
}

template<typename ... Component>
EntityView<Component...> EntityManager::GetView()
{
    // Create view from list of component types
}

1 Ответ

0 голосов
/ 21 июня 2019

То, что вы описываете, звучит очень похоже на шаблон строителя , и вы можете получить подобное поведение с синтаксисом, подобным этому:

// view would be EntityView<Location, Enemy, Flying> 
auto view = makeBlueprint()
              .AddComponent<Location>(...)
              .AddComponent<Enemy>(...)
              .AddComponent<Flying>(...)
              .GetView();

При этом будет использоваться динамический компоновщик, в котором каждый добавленный компонент создаст немного другой компоновщик, такой как Builder<>, тогда .AddComponent<Location>() вернет Builder<Location>, а затем Builder<Location, Enemy> и т. Д.

Однако, это все еще не позволяет динамическую типизацию; что-то вроде этого не будет работать:

auto blueprint = makeBlueprint()
                   .AddComponent<Location>(...)
                   .AddComponent<Enemy>(...);

if (... some check ...)
    blueprint = blueprint.AddComponent<Flying>(...);

auto view = blueprint.GetView();

Я сомневаюсь, что это решает вашу проблему, поскольку все еще должно быть динамически типизировано и не "динамически собирается во время выполнения". Но я надеюсь, что это даст вам понимание независимо.

...