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


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



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

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


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

Пусть ужо сам что-то скажет.
...
Рейтинг: 0 / 0
08.08.2013, 17:39
    #38360087
Кривой
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Шаблон и char[]
Разные значит, что ни один из предложенных вами вариантов не подхватывается и если смотреть в отладчике то при разной размерности массива создаются разные функции типа:
Код: 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
08.08.2013, 20:43
    #38360197
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Шаблон и char[]
Кривой,

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

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

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

Делайте так:
Код: 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
08.08.2013, 20:53
    #38360203
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Шаблон и char[]
ПРоблему наверное можно решить, применив частичную специализацию,
и точно можно решить, просто определив нешаблонную функцию, принимающую char*.

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

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

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

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

Еще раз говорю - там в функцию передается указатель на массив, а не ссылка, которая неявно умеет преобразовываться в указатель на данные .
Поэтому без обертки преобразующей указатель в ссылку не обойтись.
...
Рейтинг: 0 / 0
09.08.2013, 09:53
    #38360443
Кривой
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Шаблон и char[]
Инстанцировать не получается, так как там именно указатель на массив определенного размера.
Суть задачи заключается в облегчении привязки, причем на этапе компиляции.
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
09.08.2013, 09:55
    #38360444
Кривой
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Шаблон и char[]
В нескольких экземплярах не устраивает то, что я не могу инстанцировать одну функцию для всех массивов.
...
Рейтинг: 0 / 0
09.08.2013, 09:59
    #38360448
Кривой
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Шаблон и char[]
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
09.08.2013, 10:19
    #38360468
Кривой
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Шаблон и char[]
Вот исправленные примеры:
Код: 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
09.08.2013, 11:25
    #38360562
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Шаблон и char[]
Кривой,

Приведи весь код дословно.
...
Рейтинг: 0 / 0
09.08.2013, 11:34
    #38360579
Кривой
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Шаблон и char[]
Вот код который есть сейчас. Для всех полей-массивов приходится вместо использования макроса делать отдельную инициализацию. Здесь убраны другие перегрузки, их больше.
Код: 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
09.08.2013, 11:42
    #38360587
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Шаблон и char[]
Кривой,

Ошибка -то где происходит и какая?
...
Рейтинг: 0 / 0
09.08.2013, 11:59
    #38360618
Кривой
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Шаблон и char[]
Вот код на который я исправил попытавшись применить совет 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
09.08.2013, 12:46
    #38360746
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Шаблон и char[]
Кривой,
Что по вашему должно означать вот это выражение?
Код: plaintext
1.
from<*_auto>
...
Рейтинг: 0 / 0
09.08.2013, 13:32
    #38360830
Кривой
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Шаблон и char[]
По моему оно должно создавать инстанс шаблона
template <class T> bool from(void *value, void *rec, char *out)

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


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