Как передать в функцию указатель на шаблон?
От: Аноним  
Дата: 04.10.05 13:26
Оценка:
Как передать в функцию указатель на параметризированную структуру, а определить тип структуры уже внутри этой функции:


// объявление шаблона
template <class Type>
struct PROTO{
// ...
Type str;
};

typedef struct proto1 {
// ...
}proto1;

typedef struct proto2 {
// ...
}proto2;


...

// здесь я создаю параметризованные объекты
PROTO<proto1> param1;
PROTO<proto2> param2;

// здесь надо вызвать функцию и передать в качестве параметра объект param1 или param2
Func(param1);
Func(param2);



// прототип функции
void Func(const PROTO<class Type>&);

// определение функции
void Func(const PROTO<class Type>& s)
{
// ...
}

Так не работает. А как правильно? Буду признателен за помощь
Re: Как передать в функцию указатель на шаблон?
От: Bell Россия  
Дата: 04.10.05 13:32
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Как передать в функцию указатель на параметризированную структуру, а определить тип структуры уже внутри этой функции:





...

А>// прототип функции
template<class Type>
А>void Func(const PROTO<class Type>&);

А>// определение функции
template<class Type>
А>void Func(const PROTO<class Type>& s)
А>{
А>    // ...
А>}


ЗЫ
Во избежание дальнейших проблем лучше поместить определение Func в заголовок на место объявления
Любите книгу — источник знаний (с) М.Горький
Re[2]: Как передать в функцию указатель на шаблон?
От: Bell Россия  
Дата: 04.10.05 13:36
Оценка:
Здравствуйте, Bell, Вы писали:

B>Здравствуйте, Аноним, Вы писали:


А>>Как передать в функцию указатель на параметризированную структуру, а определить тип структуры уже внутри этой функции:




B>
А>>// определение функции
B>template<class Type>
А>>void Func(const PROTO<class Type>& s)
А>>{
А>>    // ...
А>>}
B>


Ключевое слово class в списке параметров конечно же лишнее. Правильно вот так:
// определение функции
template<class Type>
void Func(const PROTO<Type>& s)
{
    // ...
}
Любите книгу — источник знаний (с) М.Горький
Re[3]: Как передать в функцию указатель на шаблон?
От: Аноним  
Дата: 04.10.05 13:41
Оценка:
Здравствуйте, Bell, Вы писали:



B>>
А>>>// определение функции
B>>template<class Type>
А>>>void Func(const PROTO<class Type>& s)
А>>>{
А>>>    // ...
А>>>}
B>>


B>
B>// определение функции
B>template<class Type>
B>void Func(const PROTO<Type>& s)
B>{
B>    // ...
B>}
B>


Спасибо, так работает. Т.е. для того чтобы, фукнция могла принимать параметризованные параметры, и конкретизировать их в run-time'е ее необходимо сделать также параметризированной.
Re[4]: Как передать в функцию указатель на шаблон?
От: Bell Россия  
Дата: 04.10.05 13:51
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Спасибо, так работает. Т.е. для того чтобы, фукнция могла принимать параметризованные параметры, и конкретизировать их в run-time'е ...

В run-time'е в данном случае ничего не конкретизируется. Все происходит в compile-time: при необходимости компилятор генерирует нужную функцию из шаблона и генерирует код вызова этой функции.

А>...ее необходимо сделать также параметризированной.

Как правило, это лучший вариант, но никто не запрещает явно перегрузить нужную функцию:

void Func(const PROTO<proto1>& p)
{
//...
}

void Func(const PROTO<proto2>& p)
{
//...
}

...

Любите книгу — источник знаний (с) М.Горький
Re[5]: Как передать в функцию указатель на шаблон?
От: Аноним  
Дата: 04.10.05 14:17
Оценка:
Здравствуйте, Bell, Вы писали:


B>Как правило, это лучший вариант, но никто не запрещает явно перегрузить нужную функцию:

типов может быть до 20-ти, поэтому перегрузка не подходит.

B>В run-time'е в данном случае ничего не конкретизируется. Все происходит в compile-time: при необходимости компилятор генерирует нужную функцию из шаблона и генерирует код вызова этой функции.

Но, как все-таки в функции определить какой тип получен?

// объявление шаблона
template <class Type>
struct PROTO{
int p;
Type str;
};

typedef struct proto1 {
int p1;
}proto1;

typedef struct proto2 {
int p2;
}proto2;

PROTO<proto1> param1;
PROTO<proto2> param2;

...

Func(param1);
Func(param2);

// определение функции
template <class Type>
void Func(const PROTO<class Type>& s)
{
int a = s.p; // нет ошибки
int b = s.str.p1; // error C2039 p1 is not member of proto2
int c = s.str.p2; // error C2039 p2 is not member of proto1
}
Re[6]: Как передать в функцию указатель на шаблон?
От: Bell Россия  
Дата: 04.10.05 14:40
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Но, как все-таки в функции определить какой тип получен?

Шаблон функции используется тогда, когда ее реализация не зависит от параметра шаблона. Если же в зависимости от типа требуется различная реализация, то тут нужно использовать или перегрузку. Если из общей стаи возможных параметров выбиваются только несколько типов, то обычно пишется один шаблон функции и перегрузки для "особых" случаев.
Если же реализация Func сильно зависит от типа параметра, то не логичнее ли сделать ее членом?
Любите книгу — источник знаний (с) М.Горький
Re[6]: Как передать в функцию указатель на шаблон?
От: Erop Россия  
Дата: 04.10.05 14:41
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Но, как все-таки в функции определить какой тип получен?


Специализации помогут нам

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

Может боьше про задачу расскажешь?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[6]: Как передать в функцию указатель на шаблон?
От: ssm Россия  
Дата: 04.10.05 15:38
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Но, как все-таки в функции определить какой тип получен?


1. перегрузка (если нет возможности расширять Type)
void FuncImpl(const proto1 &proto);
void FuncImpl(const proto2 &proto);

template <class Type>
void Func(const PROTO<class Type>& s)
{
   int a = s.p;   // нет ошибки
   FuncImpl(s.str);
}


2. характеристики/стратегии(если нет возможности расширять Type)
template<typename T> struct ProtoTraits
{
  static void FuncImpl(Type &t);
};

template<> struct ProtoTraits<proto1>
{
  static void FuncImpl(Type &t);
};

template<> struct ProtoTraits<proto2>
{
  static void FuncImpl(Type &t);
};

template <class Type>
void Func(const PROTO<class Type>& s)
{
   int a = s.p;   // нет ошибки
   ProtoTraits<Type>::FuncImpl(s.p);
}


3. -добавить void FuncImpl в Type (если есть возможность расширять Type)

Выбор за Вами
Re[7]: Как передать в функцию указатель на шаблон?
От: Аноним  
Дата: 04.10.05 15:40
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, Аноним, Вы писали:


А>>Но, как все-таки в функции определить какой тип получен?


E>Специализации помогут нам


E>Но зачем тебе шаблоны и вообще перегрузка такая хитрая, если у тебя всё разное и поля и типы и работа с ними по-разному стрится, но при этом перегружать функции нехорошо?


E>Может боьше про задачу расскажешь?



В структуре PROTO

template <class Type>
struct PROTO{
// ...
Type str;
};

typedef struct proto1 {
// ...
static const pid = 1;
}proto1;

typedef struct proto2 {
// ...
static const pid = 2;
}proto2;

передаются конфигурационные параметры для создания объектов разных типов. И эти параметры очень сильно отличаются от объекта к объекту, но есть и ряд общих параметров. Поэтому я и подумал о шаблоне, где

Type str;

описывает те параметры, которые отличаются.
А использовать объекты структур PROTO надо таким образом:



template <class Type>
int CreateObjects(const Proto<Type>& s)
{
Protocol* ptr = NULL;
HANDLE handleStream = NULL;
unsigned nIdStream = 0;

try
{
switch(s.str.pid)
{
case 0:
ptr = new Class1(s); // здесь надо передать нужную структуру, но компилятор не понимает этого
break;

case 1:
ptr = new Class2(s);
break;

...

default:
return 1;
}
}
catch(std::bad_alloc)
{
return 1;
}

return 0;
}
Re[8]: Как передать в функцию указатель на шаблон?
От: ssm Россия  
Дата: 04.10.05 15:50
Оценка:
Здравствуйте, Аноним, Вы писали:


А>передаются конфигурационные параметры для создания объектов разных типов. И эти параметры очень сильно отличаются от объекта к объекту, но есть и ряд общих параметров. Поэтому я и подумал о шаблоне, где


ну дык:

Protocol *CreateProtocol(const proto1 &proto);
Protocol *CreateProtocol(const proto2 &proto);

template <class Type>
void CreateObjects(const PROTO<class Type>& s)
{
    Protocol*    ptr = NULL;
    //...
        ptr = CreateProtocol(s.str);
        //...
}


Re[9]: Как передать в функцию указатель на шаблон?
От: Аноним  
Дата: 04.10.05 16:06
Оценка:
Здравствуйте, ssm, Вы писали:

ssm>Здравствуйте, Аноним, Вы писали:



А>>передаются конфигурационные параметры для создания объектов разных типов. И эти параметры очень сильно отличаются от объекта к объекту, но есть и ряд общих параметров. Поэтому я и подумал о шаблоне, где


ssm>ну дык:


ssm>
ssm>Protocol *CreateProtocol(const proto1 &proto);
ssm>Protocol *CreateProtocol(const proto2 &proto);

ssm>template <class Type>
ssm>void CreateObjects(const PROTO<class Type>& s)
ssm>{
ssm>    Protocol*    ptr = NULL;
ssm>    //...
ssm>        ptr = CreateProtocol(s.str);
ssm>        //...
ssm>}
ssm>


ssm>


и реализовывать все варианты функции CreateProtocol, их может быть достаточно много
Re[10]: Как передать в функцию указатель на шаблон?
От: ssm Россия  
Дата: 04.10.05 16:14
Оценка:
Здравствуйте, Аноним, Вы писали:


А>и реализовывать все варианты функции CreateProtocol, их может быть достаточно много


их будет ровно столько, сколько у тебя есть типов proto
Re: Как передать в функцию указатель на шаблон?
От: Erop Россия  
Дата: 04.10.05 16:20
Оценка:
Здравствуйте, Аноним, есть тогда такое предложение:

1) Вместо текстовой строки, использовать какую-то боле удобную форму архива данных, например класс, который по имени аргумента и его типу умеет получать/возвращать значение

2) у всех типов protoXXX завести конструктор от такого объекта, тогда и упаковывать/распаковывать аргументы будет удобно, и шаблон нужный написать, и иерархию классов protoXXX можно будет завести, если они похожи, и отличаются только нескколькими параметрами.
Кроме того, всю эту кухню можно будет удобно логировать
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: Как передать в функцию указатель на шаблон?
От: RaGod  
Дата: 05.10.05 08:55
Оценка:
А если воспользоваться оператором typeid ??
Так не получиться ?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.