powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Шаблоны в контейнере
16 сообщений из 16, страница 1 из 1
Шаблоны в контейнере
    #38715143
Фотография Poppler
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Стоит задача сложить шаблоны в контейнер и затем их извлекать по индексу.

Есть вот такой условный код:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
struct One { };
struct Two { };

template <class T>
struct Creater
{
    T* make() { return new T(); }
};

std::vector<Creater> vec;
vec.push_back(Creator<One>());
vec.push_back(Creator<Two>());



он не работает по понятным причинам, но как сделать, чтобы работал? Если никак, как можно добиться аналогичного поведения с помощью шаблонов?
...
Рейтинг: 0 / 0
Шаблоны в контейнере
    #38715146
Фотография Poppler
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
и затем их извлекать по индексу.

извлекать, чтобы вызвать нужную специализацию Creater::make();
...
Рейтинг: 0 / 0
Шаблоны в контейнере
    #38715197
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Для One и Two нужно завести базовый класс и добавлять через указатель на него.
...
Рейтинг: 0 / 0
Шаблоны в контейнере
    #38715358
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
On 07.08.2014 17:34, Poppler wrote:

> Стоит задача сложить шаблоны в контейнер и затем их извлекать по индексу.

Надо начать с того, что шаблоны нельзя никуда сложить, ни в какой
контейнер. Туда даже классы нельзя сложить. Только объекты каких-то
типов или классов.


> Есть вот такой условный код:
>
> struct One { };
> struct Two { };
>
> template <class T>
> struct Creater
> {
> T* make() {return new T(); }
> };

> std::vector<Creater> vec;
> vec.push_back(Creator<One>());
> vec.push_back(Creator<Two>());


> он не работает по понятным причинам, но как сделать, чтобы работал? Если
> никак, как можно добиться аналогичного поведения с помощью шаблонов?


Для начала, так писать нельзя.

Код: plaintext
1.
std::vector<Creater> vec;



std::vector должен параметризироваться классом или типом, а Creater --
шаблон.

Нужно инстанциировать этой шаблон сначала.


Код: plaintext
1.
2.
std::vector< Creater<One> > vec;
vec.push_back(Creator<One>());



Но вот

Код: plaintext
1.
vec.push_back(Creator<Two>());



уже НЕ ПОЛУЧИТЬСЯ, потому что Creator<One> и Creator<Two> -- два разных,
ничем друг с другом не связанных класса.

Как тут советовали

"Для One и Two нужно завести базовый класс и добавлять через указатель
на него."

не получится тоже.

Ещё раз, Creator<One> и Creator<Two> -- абсолютно разные классы, они
никак не связаны друг с другом, и их указатели также несоотносимы. Также
не поможет Creator< CommonParentOfOneAndTwo >, он также несоотносим с
предыдущими инстанциациями этого шаблона.
Их можно было бы запихать в vector, преобразовав в void*, но потом-то
надо будет как-то reinterpret_cast-ить обратно, а на основе чего ?


В данном конкретном случае лучше
забыть о существовании шаблонов.

реализовать всё по паттерну Abstract Factory.

Или -- что вообще просто -- хранить в векторе указатели на функции,
создающие объект класса.

Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Шаблоны в контейнере
    #38715384
Фотография Духовные скрепы
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivНадо начать с того, что шаблоны нельзя никуда сложить, ни в какой
контейнер. Туда даже классы нельзя сложить. Только объекты каких-то
типов или классов.

Раз вы такой дотошный проверьте ещё что нибудь, например орфографию и т.п. Если непонятно то уточню, так было короче написать, смысл передавался верно, товарищ выше понял, что я хотел.

MasterZivДля начала, так писать нельзя.

Код: plaintext
1.
std::vector<Creater> vec;



std::vector должен параметризироваться классом или типом, а Creater -- шаблон.

Может ещё раз перечитаете моё первое сообщение где я написал, что код условный и он не работает по понятным причинам?
Я ведь не спрашивал, что не правильно конкретно в этом коде, я спросил как написать правильно то, что я хочу выразив условным кодом.

MasterZivуже НЕ ПОЛУЧИТЬСЯ, потому что Creator<One> и Creator<Two> -- два разных,
ничем друг с другом не связанных класса.

Ну надо же, а мы то и не знали... Спасибо кеп.

MasterZivЕщё раз, Creator<One> и Creator<Two> -- абсолютно разные классы, они
никак не связаны друг с другом, и их указатели также несоотносимы. Также
не поможет Creator< CommonParentOfOneAndTwo >, он также несоотносим с
предыдущими инстанциациями этого шаблона.

Т.е. вы готовы поручиться, что с использованием статического полиморфизма это никак не сделать?

MasterZivреализовать всё по паттерну Abstract Factory.

В данном случае уже есть реализация Abstract Factory которая переписывается на шаблоны.

MasterZivИли -- что вообще просто -- хранить в векторе указатели на функции,
создающие объект класса.

Я спрашивал не как сделать проще, реализацию как проще уже есть, я спрашивал как сделать то что я хочу.
...
Рейтинг: 0 / 0
Шаблоны в контейнере
    #38715390
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Попался клон.
...
Рейтинг: 0 / 0
Шаблоны в контейнере
    #38715591
Strangecat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Poppler
он не работает по понятным причинам, но как сделать, чтобы работал? Если никак, как можно добиться аналогичного поведения с помощью шаблонов?

Ближайшее чего можно сделать в реальности с помощью шаблонов это использовать Boost.variant.
...
Рейтинг: 0 / 0
Шаблоны в контейнере
    #38715902
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Духовные скрепы
Т.е. вы готовы поручиться, что с использованием статического полиморфизма это никак не сделать?


Очень похоже на то. По крайней мере я лично не знаю способ, как это сделать. А это 80-90% надёжности.
Но есть одно но -- я не очень люблю шаблоны, если можно так сказать. Они плохо сочетаются со всеми другими
технологиями программирования, доступными в С++. Я их использую там, и только там, где их использование очевидно
принесёт какие-то положительные плоды, но не более.

Ну и главное -- как ты это запихаешь всё в фабрику, там-то статический полиморфизм не работает...

Духовные скрепыMasterZivреализовать всё по паттерну Abstract Factory.
В данном случае уже есть реализация Abstract Factory которая переписывается на шаблоны.


А в чём цель? Просто применить шаблоны ?
Как бы Abstract Factory нельзя полностью без потери функционала переписать на шаблоны, она ориентируется на полиморфизм в runtime, а шаблонный полиморфизм -- только compile time. Ты должен будешь потерять какой-то функциональ, что, возможно, допустимо в каком-то конкретном случае использования.

Духовные скрепыЯ спрашивал не как сделать проще, реализацию как проще уже есть, я спрашивал как сделать то что я хочу.

Возможно, я (и другие читатели) не очень хорошо представляю, что ты хочешь.
Может быть тебе стоит объяснить это более детально.
...
Рейтинг: 0 / 0
Шаблоны в контейнере
    #38716038
Фотография Духовные скрепы
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если кратко я хотел, что-то типа этого:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
#include <iostream>
#include <vector>
using namespace std;

class Base
{
public:
    virtual void doSome() = 0;
};
class A : public Base
{
public:
   void doSome() { }
};

class B : public Base
{
public:
   void doSome() { }
};

class Wrapper
{
public:
    typedef Base*(*func)();

    Wrapper(func _f) : f(_f) { }

    func f;
};

template <class T>
T* make() { return new T(); }

template <class T>
Wrapper makeType() { return Wrapper((Wrapper::func)&make<T>); }

int main()
{
    std::vector<Wrapper> v;
    v.push_back(makeType<A>());
    v.push_back(makeType<B>());

    auto Base = v.front().f();

    return 0;
}



только хотелось, чтобы не было отдельных шаблоных функций, а был шаблонный класс
...
Рейтинг: 0 / 0
Шаблоны в контейнере
    #38716044
Фотография Духовные скрепы
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fixed

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
int main()
{
    std::vector<Wrapper> v;
    v.push_back(makeType<A>());
    v.push_back(makeType<B>());

    auto pB = v.front().f();
    pB->doSome();

    return 0;
}
...
Рейтинг: 0 / 0
Шаблоны в контейнере
    #38716046
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Духовные скрепыЕсли кратко я хотел, что-то типа этого:
Код: plaintext
1.
2.
#include <iostream>
...




Лучше бы ты словами написал...
...
Рейтинг: 0 / 0
Шаблоны в контейнере
    #38716050
Фотография Духовные скрепы
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivЛучше бы ты словами написал...

Словами, нужно сложить типы в контейнер и извлекать нужный тип для создания объекта. Только хотелось бы вместо шаблонных функций заюзать шаблонный класс(ы).
...
Рейтинг: 0 / 0
Шаблоны в контейнере
    #38716253
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
On 08.08.2014 15:48, Духовные скрепы wrote:

> Словами, нужно сложить типы в контейнер и извлекать нужный тип для
> создания объекта.

Это метаклассы надо делать, и их хранить.
При чём язык С++ метаклассы никак не поддерживает, и тебе придётся
метакласс отдельно РУКАМИ (ну или с помощью магии макросов) описывать,
параллельно с основными классами, и С++ тебе в этом никак не поможет.


Только хотелось бы вместо шаблонных функций заюзать
> шаблонный класс(ы).

Ну и при чём тут шаблоны ? Вообще ни при как.


Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Шаблоны в контейнере
    #38716300
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это задачка детская. Но в С++ почему-то все хотят "птичьего молока" вместе с ее решением.
...
Рейтинг: 0 / 0
Шаблоны в контейнере
    #38716472
?
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
?
Гость
Так?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
#include <iostream>
#include <vector>

using namespace std;
class Base
{
public:
    virtual void doSome() = 0;
};

template <class T> class Wrapper : public Base {
public:
	static Base * makeMe() { return new T; }
};


class A : public Wrapper<A> {
	void doSome() { cout << "A\n"; }
};

class B : public Wrapper<B> {
	void doSome() { cout << "B\n"; }
};

int main(int argc, char* argv[])
{
	vector<Base*(*)()> v;
	v.push_back(A::makeMe);
	v.push_back(B::makeMe);
	(*v.front())()->doSome();
	return 0;
}
...
Рейтинг: 0 / 0
Шаблоны в контейнере
    #38716665
BagaBaga
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вероятно, топикстартеру курить до просветления:

http://video.ch9.ms/ch9/7469/5deda136-d074-445d-8ac8-8a6983507469/GN13SeanParentInheritanceistheBaseClassofEvil_high.mp4 int main()
{
document_t document;
document.emplace_back(0);
document.emplace_back(string("Hello!"));
document.emplace_back(document);
document.emplace_back(my_class_t());
draw(document, cout, 0);
}


Если здесь танец вокруг draw, то у него будет вокруг собственного make.
...
Рейтинг: 0 / 0
16 сообщений из 16, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / Шаблоны в контейнере
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]