Я хотел бы создать функцию шаблона, которая создавала бы объект на основе имени типа шаблона и пакета параметров.
Я создал функцию, которая должна создавать объект на основе имени типа из шаблона, и я также хотел бы передать пакет параметров в этот шаблон, чтобы передать параметры конструктору. Это правильно?:
template<typename TComponent, typename... Args>
void CreateComponent(Args... args)
{
std::shared_ptr<TComponent> component = std::make_shared<TComponent>(args ...);
}
Я также хотел передать эти параметры другой функции, например:
template<typename TComponent, typename... Args>
void AddComponent(Args... args)
{
m_world->AddComponent<TComponent, Args>(m_id, args...);
}
Но компилятор возвращает ошибку "Пакет параметров 'args' должен быть расширен в этом контексте"
Возможно ли вообще добиться того, чего я хочу достичь?





But compiler returns an error " 'args' parameter pack must be expanded in this context"
Да: вы забыли расширить типы
m_world->AddComponent<TComponent, Args...>(m_id, args...);
// ...................................^^^
Как указал Jarod42, в зависимости от обстоятельств вы можете избежать явного расширения Args....
m_world->AddComponent<TComponent>(m_id, args...);
// no more Args...
и пусть компилятор выводит типы через args... (но мы должны увидеть определение AddComponent()).
В любом случае, я не вижу ошибок в вашей функции CreateComponents(), но, как правильно говорит Франсуа Андрие в комментарии, вы не используете идеальную переадресацию.
Это слишком большой аргумент, чтобы объяснять его в ответе, но таким образом вы отказываетесь от преимуществ семантики (то есть: вы, возможно, делаете несколько ненужных копий).
Ниже приведена ваша функция CreateComponents(), обеспечивающая идеальную переадресацию.
template <typename TComponent, typename ... Args>
void CreateComponent (Args && ... args)
{ // .....................^^ forwarding reference added
std::shared_ptr<TComponent> component
= std::make_shared<TComponent>(std::forward<Args>(args)...);
} // ..............................^^^^^^^^^^^^^^^^^^^^^^^^
, Args..., вероятно, можно опустить, как выведено.
@FrançoisAndrieux - да; Я добавил кое-что. Спасибо.
Ладно, попался! Спасибо за вашу помощь !
С идеальной переадресацией:
template <typename T, typename... Args> void CreateComponent(Args&&... args) { auto component = std::make_shared<T>(std::forward<Args>(args)...);}