powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Шаблон и char[]
25 сообщений из 26, страница 1 из 2
Шаблон и char[]
    #38359853
Кривой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть несколько структур в которых объявлены поля char[??] name различной размерности.
Есть шаблон, который принимает указатель на данные
Код: plaintext
1.
2.
template <typename T>
void foo(T *ttt);


Подскажите как инстанцировать ее или как должно выглядеть определение перегруженной функции что бы использовалась именно она для всех полей не смотря на размерность, а то для каждой размерности создается свой экземпляр.
...
Рейтинг: 0 / 0
Шаблон и char[]
    #38359881
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
КривойЕсть несколько структур в которых объявлены поля char[??] name различной размерности.
Есть шаблон, который принимает указатель на данные
Код: plaintext
1.
2.
template <typename T>
void foo(T *ttt);


Подскажите как инстанцировать ее


Код: plaintext
1.
2.
template void foo<char>(T *);
template void foo<int>(T *);



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

На размерность чего ? В общем, переводи на русский.
...
Рейтинг: 0 / 0
Шаблон и char[]
    #38359926
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
КривойПодскажите как инстанцировать ее или как должно выглядеть определение перегруженной функции что бы использовалась именно она для всех полей не смотря на размерность, а то для каждой размерности создается свой экземпляр.
На самом деле ничего не нужно специально инстанцировать.
Никаких отдельных экземпляров не создается для данного кода (при условии что все массивы с одним и тем же типом элементов, например char).
Вероятно под экземпляром вы понимаете нечто, что в С++ имеет иное название.
...
Рейтинг: 0 / 0
Шаблон и char[]
    #38359937
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZiv
Код: plaintext
1.
template void foo<char>(T *);



Не совсем так, тут Т - необъявлен :)

Вот так явно инстанцируется:
Код: plaintext
1.
2.
3.
template void foo<char>(char *);
// или тоже самое но короче:
template void foo(char *);


Но это ему не надо.
...
Рейтинг: 0 / 0
Шаблон и char[]
    #38359943
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Про разные экземпляры.
Так как шаблон может инстанцироваться в разных единицах трансляции, то потенциально в каждой из них может быть создана копия кода. Но это зависит не от объявления шаблона, или типа аргумента, а от того как реализована генерация кода в компиляторе.
...
Рейтинг: 0 / 0
Шаблон и char[]
    #38360086
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky,

Пусть ужо сам что-то скажет.
...
Рейтинг: 0 / 0
Шаблон и char[]
    #38360087
Кривой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Разные значит, что ни один из предложенных вами вариантов не подхватывается и если смотреть в отладчике то при разной размерности массива создаются разные функции типа:
Код: plaintext
1.
2.
3.
void foo(char[40] *ttt);
void foo(char[50] *ttt);
void foo(char[60] *ttt);


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

Проблема в том, что передается всегда указатель, а не просто поле:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
struct fffff{
char name[40];
char dep[50];
int id;
} fffff;
template <typename T>
void foo(T *ttt);

void main()
{
fffff A;
foo(&A.id);
foo(&A.name);//вот тут 
foo(&A.dep);//и вот тут создаются разные функции
}


Если бы передавался просто параметр, а не указатель проблемы бы не было, предложенными вами способами она бы решалась.
...
Рейтинг: 0 / 0
Шаблон и char[]
    #38360197
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кривой,

Вы шо не могли сразу сказать что передаете указатель на массив?
Как по вашему мы должны были догадаться что вы извращаетесь?
В этом случае естественно каждый размер массива инстанцирует отдельную функцию, потому что размер массива - часть типа.
...
Рейтинг: 0 / 0
Шаблон и char[]
    #38360200
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky,

Точнее, он инстанциирует функции для типов "ссылка на массив определённого размера".
...
Рейтинг: 0 / 0
Шаблон и char[]
    #38360201
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivТочнее, он инстанциирует функции для типов "ссылка на массив определённого размера".

Какая ссылка? Там взятие адреса &
...
Рейтинг: 0 / 0
Шаблон и char[]
    #38360202
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кривой,

Делайте так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
template <typename ElemType>
void foo(ElemType *data, size_t len)
{
    cout << data[0] << "/" << len << endl;
}

template <typename ArrType>
void foo(ArrType *arr)
{
    foo(*arr, sizeof(*arr));
}



Второй шаблон размножится, но из себя вызовет единственный экземпляр первого.
...
Рейтинг: 0 / 0
Шаблон и char[]
    #38360203
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ПРоблему наверное можно решить, применив частичную специализацию,
и точно можно решить, просто определив нешаблонную функцию, принимающую char*.

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

Также можно было бы явно инстанциировать функции в месте вызова, явно указывая тип шаблонного парамерта (char*),
но это надо верояно много кода менять.
...
Рейтинг: 0 / 0
Шаблон и char[]
    #38360204
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А вообще непонятно, что вас не устраивает в том что есть несколько экземпляров.
...
Рейтинг: 0 / 0
Шаблон и char[]
    #38360205
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly MoskovskyMasterZivТочнее, он инстанциирует функции для типов "ссылка на массив определённого размера".

Какая ссылка? Там взятие адреса &

А кстати да.
Ну и зря он адрес берёт...
...
Рейтинг: 0 / 0
Шаблон и char[]
    #38360206
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZiv,

Еще раз говорю - там в функцию передается указатель на массив, а не ссылка, которая неявно умеет преобразовываться в указатель на данные .
Поэтому без обертки преобразующей указатель в ссылку не обойтись.
...
Рейтинг: 0 / 0
Шаблон и char[]
    #38360443
Кривой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Инстанцировать не получается, так как там именно указатель на массив определенного размера.
Суть задачи заключается в облегчении привязки, причем на этапе компиляции.
template <typename T> void foo(char *ret, void *val);
каждый вариант такой функции инстанцируется, для нужных мне типов:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
template <> void foo<char *>(char *ret, void *val);
{
  strcpy(ret, val);
}
template <> void foo<int>(char *ret, void *val);
{
  sprintf(ret, "%d", *((int*)(val)));
}


для автоматического заполнения указателя на функцию используется след. связка:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
  template <typename T>
  void Fill(mystruc *ret, int _offset, T *_auto);
  {
    ...
    ret->print =  foo<T*>;
  }
#define _Fill(ret, rec, Field) SelectedField(Name, offsetof(rec, Field), &((rec*)0)->Field)


Макрос используется, что бы можно было оперировать только структурой и ее полем, через указатель на поле сделано так как от нулевого указателя значение невозможно получить. Вообще Fill в реальности конструктор.
Все конечно криво, но я не нашел вариант лучше. Если у кого есть варианты буду очень признателен.
...
Рейтинг: 0 / 0
Шаблон и char[]
    #38360444
Кривой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В нескольких экземплярах не устраивает то, что я не могу инстанцировать одну функцию для всех массивов.
...
Рейтинг: 0 / 0
Шаблон и char[]
    #38360448
Кривой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly MoskovskyКривой,

Делайте так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
template <typename ElemType>
void foo(ElemType *data, size_t len)
{
    cout << data[0] << "/" << len << endl;
}

template <typename ArrType>
void foo(ArrType *arr)
{
    foo(*arr, sizeof(*arr));
}



Второй шаблон размножится, но из себя вызовет единственный экземпляр первого.

Что-то у меня жесткий тупняк с утра. Все мои примеры кода неверные и содержат кучу опечаток. А вот этот пример я опробую. Спасибо.
...
Рейтинг: 0 / 0
Шаблон и char[]
    #38360468
Кривой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вот исправленные примеры:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
template <> void foo<char **>(char *ret, void *val);
{
  strcpy(ret, val);
}
template <> void foo<int*>(char *ret, void *val);
{
  sprintf(ret, "%d", *((int*)(val)));
}

  template <typename T>
  void Fill(mystruc *ret, int _offset, T *_auto);
  {
    ...
    ret->print =  foo<T*>;
  }
#define _Fill(ret, rec, Field) Fill(Name, offsetof(rec, Field), &((rec*)0)->Field)



А по предложенному варианту Anatoly Moskovsky, меняю
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
template <> void foo<int*>(char *ret, void *val);
на
template <> void foo<int>(char *ret, void *val);

  void Fill(mystruc *ret, int _offset, T *_auto);
  {
    ...
    ret->print =  foo<T*>;
на
    ret->print =  foo<*_auto>;
  }


и даже скомпилить не получается выводит сообщение:
error C2440: 'initializing' : cannot convert from 'bool (__cdecl *)(char *, void *)' to 'creator'
Код: plaintext
1.
typedef bool (*creator)(char *ret, void *val);
...
Рейтинг: 0 / 0
Шаблон и char[]
    #38360562
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кривой,

Приведи весь код дословно.
...
Рейтинг: 0 / 0
Шаблон и char[]
    #38360579
Кривой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вот код который есть сейчас. Для всех полей-массивов приходится вместо использования макроса делать отдельную инициализацию. Здесь убраны другие перегрузки, их больше.
Код: 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.
template <class T>
bool from(void *value, void *rec, char *out)
{
  strcpy(out, "не определено");
  return true;
}

template <>
bool from<int*>(void *value, void *rec, char *out)
{
  sprintf(out, "%d", *((int*)(value)));
  return true;
}

template <>
bool from<char **>(void *value, void *rec, char *out)
{
  strncpyz(out, (char *)value, 40);
  return true;
}

typedef bool (*creator)(void *value, void *rec, char *out);

typedef struct SelectedField {
  const char *Name;
  creator make;
  int offset;
  template <typename T>
  SelectedField(const char *_Name, int _offset, T *_auto):
      Name(_Name), offset(_offset), make(from<T*>) {}
} SelectedField;

#define _SelectedField(Name, Table, Field) SelectedField(Name, offsetof(Table, Field), &((Table*)0)->Field)
//создание
SelectedField *A = new SelectedField("Бла-бла", NameOfStruct, NameOfField);



По хорошему отказался бы и от макроса, оставив только шаблоны, но идей нет никаких.
...
Рейтинг: 0 / 0
Шаблон и char[]
    #38360587
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кривой,

Ошибка -то где происходит и какая?
...
Рейтинг: 0 / 0
Шаблон и char[]
    #38360618
Кривой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вот код на который я исправил попытавшись применить совет Anatoly Moskovsky
Код: 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.
template <class T>
bool from(void *value, void *rec, char *out)
{
  strcpy(out, "не определено");
  return true;
}

template <>
bool from<int>(void *value, void *rec, char *out)
{
  sprintf(out, "%d", *((int*)(value)));
  return true;
}

template <>
bool from<char *>(void *value, void *rec, char *out)
{
  strncpyz(out, (char *)value, 40);
  return true;
}

typedef bool (*creator)(void *value, void *rec, char *out);

typedef struct SelectedField {
  const char *Name;
  creator make;
  int offset;
  template <typename T>
  SelectedField(const char *_Name, int _offset, T *_auto):
      Name(_Name), offset(_offset), make(from<*_auto>) {}
} SelectedField;

#define _SelectedField(Name, Table, Field) SelectedField(Name, offsetof(Table, Field), &((Table*)0)->Field)



Ошибка: error C2440: 'initializing' : cannot convert from 'bool (__cdecl *)(void *, void *, char *)' to 'creator'
Ошибка в шаблонном конструкторе VS2005.
Выделил места которые менял.
...
Рейтинг: 0 / 0
Шаблон и char[]
    #38360746
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кривой,
Что по вашему должно означать вот это выражение?
Код: plaintext
1.
from<*_auto>
...
Рейтинг: 0 / 0
Шаблон и char[]
    #38360830
Кривой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
По моему оно должно создавать инстанс шаблона
template <class T> bool from(void *value, void *rec, char *out)

по типу T, на который _auto является указатель. Может я что то не так понимаю?
...
Рейтинг: 0 / 0
25 сообщений из 26, страница 1 из 2
Форумы / C++ [игнор отключен] [закрыт для гостей] / Шаблон и char[]
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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