Фабрика C++ типа контейнера без определения типа элемента контейнера

Основываясь на этой теме, мне интересно, можно ли создать фабричный класс, который бы предоставлял тип контейнера, не определяя тип элемента контейнера.

Что-то вроде:

template <typename t_container>
class factory {
public:
  using container = t_container;
}

так что что-то вроде этого, но не совсем с этим синтаксисом, потому что я знаю, что он недействителен в C++, будет работать:

...
factory<std::vector>::container<int> my_container;
...

Идея состоит в том, что factory будет определять тип контейнера, а не тип элемента, который factory::container будет содержать, оставляя это решение на усмотрение пользовательского кода.

Возможно, вы ищете параметры шаблона-шаблона? Что-то вроде godbolt.org/z/Pf5vh6TM9? Но у вас не может быть такого using, как вы написали.

cigien 19.03.2024 13:06

@cigien Почему бы и нет?

Weijun Zhou 19.03.2024 13:09

@WeijunZhou Именно по этой причине вам пришлось создать using шаблон псевдонима. Как написал ОП, это невозможно, потому что t_container вообще не был бы типом (это был бы шаблон), как показано в демонстрации, на которую я дал ссылку.

cigien 19.03.2024 13:14

ХОРОШО. Кажется, я неправильно понял, что ты имел в виду под невозможным.

Weijun Zhou 19.03.2024 13:15

кстати, factory обычно так мы называем вещь, которая что-то создает. Если вы хотите, чтобы это был просто «какой-то шаблон, в котором пользователь указывает тип элемента», я бы дал ему другое имя.

463035818_is_not_an_ai 19.03.2024 14:14
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
5
68
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы хотите, чтобы t_container был шаблоном, поэтому template <typename t_container> неверно (он объявляет t_container типом, но std::vector не является типом). И после этого ваше объявление using неверно, поскольку предполагает, что t_container является типом.

Вы можете сделать это, используя аргумент шаблона шаблона:

#include <vector>


template <template <typename...> class C>
struct factory {
    template <typename T>
    using container = C<T>;

    template <typename T> 
    container<T> make() { return C<T>{};}

};


int main ()
{
   auto vec_int = factory<std::vector>{}.make<int>();
}

Живая демо

Один и тот же factory<std::vector> может создавать векторы с элементами разного типа, как показано в шаблоне псевдонима члена и шаблоне функции-члена.

Существует только одна небольшая проблема при использовании контейнера с аргументами шаблона, не относящимися к типу. Вышеупомянутое не будет работать для std::array, поскольку его второй аргумент — это size_t, а не тип. Также, например, std::map не охвачен вышеизложенным, поскольку тип его элемента определяется двумя параметрами (тип ключа и значения).

Очень хорошее решение, но мне нужно, чтобы «vec_int» был атрибутом класса. «фабрика» будет поставщиком типов, а не создателем объекта.

canellas 19.03.2024 13:14

@canellas и? Вы можете удалить метод, если он вам не нужен.

463035818_is_not_an_ai 19.03.2024 13:15

@canellas factory<std::vector>::container<int> my_container;, о котором ты просишь, здесь. Не знаю, почему вы думаете, что «но мне нужно, чтобы vec_int был атрибутом класса» будет проблемой.

463035818_is_not_an_ai 19.03.2024 13:18

Вы правы, ваше решение - это то, что мне нужно. Большое спасибо!

canellas 19.03.2024 13:21

Другие вопросы по теме