Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.78/18: Рейтинг темы: голосов - 18, средняя оценка - 4.78
24 / 10 / 5
Регистрация: 30.01.2015
Сообщений: 175

Шаблон для пользовательских типов данных

15.02.2015, 16:04. Показов 4046. Ответов 16
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
В общем имееются две функции. Одна принимает тип данных string другая char[]. Функции выполняют одну и ту же задачу. Вопрос как сделать шаблон который бы принимал только эти два типа данных(string и char[])?
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
15.02.2015, 16:04
Ответы с готовыми решениями:

Функции на основе пользовательских типов данных
Всем привет. Читаю книгу страуструпа и заметил там функции на основе пользовательских типов данных. Как работают обычные функции с уже...

Реализовать сохранение в базу данных полей разных типов (в том числе и пользовательских)
Здравствуйте! Подскажите как можно реализовать такую задачу: В базе данных должны быть записи, которые состоят из полей. Поля...

Возможно ли переопределение операторов для пользовательских типов?
Собственно преследуемая цель: Определить свой тип int - myint. Переопределить для него операторы как надо. Ну, например, надо мне при...

16
542 / 163 / 79
Регистрация: 23.09.2013
Сообщений: 316
15.02.2015, 16:18
Например так:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <string>
 
template <typename T>
void ShowAnyString(T string) {
  std::cout << string << '\n';
}
 
int main() {
  std::string string = "string";
  char array[] = "array";
  ShowAnyString(string);
  ShowAnyString(array);
}
Пруф работоспособности:
http://ideone.com/D3Npe9

Добавлено через 4 минуты
Или так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <string>
#include <algorithm>
#include <iterator>
 
template <typename II>
void ShowAnyString(II first, II last) {
  std::copy(first, last, std::ostream_iterator<char>(std::cout));
  std::cout << '\n';
}
 
int main() {
  std::string string = "string";
  char array[] = "array";
  ShowAnyString(std::begin(string), std::end(string));
  ShowAnyString(std::begin(array), std::end(array));
}
Пруф работоспособности:
http://ideone.com/beSWkx
0
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
15.02.2015, 16:20
Слишком просто. А если char обрабатывается древними функциями?

kol, может достаточно дать двум функциям одинаковые имена?
0
 Аватар для DiffEreD
1458 / 795 / 257
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
15.02.2015, 19:19
Лучший ответ Сообщение было отмечено kol как решение

Решение

Три варианта:
Кликните здесь для просмотра всего текста
C++
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
#include <iostream>
#include <type_traits>
#include <string>
 
template <typename T>
void print_str(const T&);
 
template <>
void print_str(const std::string& str) {
    std::cout << str << "\n";
}
 
template <>
void print_str(const char* const& str) {
    std::cout << str << "\n";
}
 
template <>
void print_str(char* const& str) {
    std::cout << str << "\n";
}
 
 
int main()
{
    std::string str = "std::string";
    const char* c_str = "const char*";
    char* c_str2 = "char*";
 
    print_str(str);
    print_str(c_str);
    print_str(c_str2);
    //print_str(42); //<-- Error
}
Кликните здесь для просмотра всего текста
C++
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
#include <iostream>
#include <type_traits>
#include <string>
 
template <typename T>
void print_str(const T& str)
{
    static_assert(   std::is_same<T, std::string>::value
                  || std::is_same<T, const char*>::value
                  || std::is_same<T, char*>::value,
                     "NOT A STR_TYPE");
    std::cout << str << "\n";
}
 
 
int main()
{
    std::string str = "std::string";
    const char* c_str = "const char*";
    char* c_str2 = "char*";
 
    print_str(str);
    print_str(c_str);
    print_str(c_str2);
    //print_str(42); //<-- Error
}
Кликните здесь для просмотра всего текста
C++
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
#include <iostream>
#include <type_traits>
#include <string>
 
template <typename T>
void print_str(const T& str, typename std::enable_if<
               std::is_same<T, std::string>::value
               || std::is_same<T, const char*>::value
               || std::is_same<T, char*>::value>::type* = nullptr)
{
    std::cout << str << "\n";
}
 
 
int main()
{
    std::string str = "std::string";
    const char* c_str = "const char*";
    char* c_str2 = "char*";
 
    print_str(str);
    print_str(c_str);
    print_str(c_str2);
    //print_str(42); //<-- Error
}
0
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
15.02.2015, 19:25
DiffEreD, ну у тебя тоже внутри функции всё подобрано так, что хоть char*, хоть string работают. А если алгоритм существенно отличается и нужно либо применить функции типа strcpy(), либо функции класса string?
0
 Аватар для DiffEreD
1458 / 795 / 257
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
15.02.2015, 19:29
Ну, так в специализациях функции вызывать то что надо для конкретного типа. Не вижу никаких проблем.
0
 Аватар для castorsky
1978 / 1082 / 87
Регистрация: 29.11.2013
Сообщений: 3,353
15.02.2015, 19:31
Цитата Сообщение от nmcf Посмотреть сообщение
А если алгоритм существенно отличается
то ни о каких шаблонах и речи быть не может.
0
 Аватар для DiffEreD
1458 / 795 / 257
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
15.02.2015, 19:32
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
template <typename T>
void print_str(const T&);
 
template <>
void print_str(const std::string& str) {
    std::cout << str.size() << "\n";
}
 
template <>
void print_str(const char* const& str) {
    std::cout << std::strlen(str) << "\n";
}
 
template <>
void print_str(char* const& str) {
    std::cout << std::strlen(str) << "\n";
}
0
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
15.02.2015, 19:41
Цитата Сообщение от castorsky Посмотреть сообщение
то ни о каких шаблонах и речи быть не может
Я имел в виду, не результат функции в целом, а то, что принцип обработки этих типов разный.
Цитата Сообщение от DiffEreD Посмотреть сообщение
в специализациях функции вызывать то что надо
Можно подробнее? Вот например, нужно определить длину этого параметра. Будет либо strlen(str), либо str.length(). Как это записать в шаблоне?
Можно просто описать 2 функции с одним именем, но разными формальными параметрами, как я и предлагал, шаблон для этого не нужен.

Добавлено через 4 минуты
DiffEreD, если просто 2 функции без template, это не верно, что ли? Твой длинный вариант что даёт?
0
 Аватар для castorsky
1978 / 1082 / 87
Регистрация: 29.11.2013
Сообщений: 3,353
15.02.2015, 20:28
Цитата Сообщение от nmcf Посмотреть сообщение
Я имел в виду, не результат функции в целом, а то, что принцип обработки этих типов разный.
списабо, кэп. А я о том что надо завернуть данные в класс для унификации интерфейсов, тогда и необходимость в шаблонах отвалится, т.к. ссылку на объект можно передать в обычную функцию. Сишная и крестовая каша к хорошему не приведет, вот уже и началось. Простой шаблон запилить стало героическим подвигом.
0
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
15.02.2015, 20:38
Т. е. реализовать самодельный string поверх char*?
Как-то теряется смысл тогда.
0
 Аватар для castorsky
1978 / 1082 / 87
Регистрация: 29.11.2013
Сообщений: 3,353
15.02.2015, 21:12
Нет. Реализовать класс foo с конструкторами string, char*. Вы же по каким-то таким эзотеричесим причинам используете и то, и другое, а хотите чтобы работало как stringchar. Значит foo.length вернет string.length или strlen(char*).

Добавлено через 19 минут
nmcf, как бы вот о чем я
C++
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
#include <iostream>
#include <string>
#include <cstring>
 
class foo{
  public:
  
    int length(std::string &str){
      return str.length();
    }
  
    int length(const char * str){
      return std::strlen(str);
    }
    
    int length(char * str){
      return std::strlen(str);
    }
};
 
int
main(int argc, char ** argv)
{
  std::string str1("asdf");
  const char * str2 = "asdf";
  
  std::cout << foo().length(str1) << std::endl;
  std::cout << foo().length(str2) << std::endl;
  
  return 0;
}
Добавлено через 2 минуты
Но это если рефакторить лень, а по хорошему, то да сделать объект с разными конструкторами, переписать все места где этот объект уже присутствует в виде string или char* и как следствие шаблон станет не нужным, но с костылем шаблончик очень даже прокатит.

Добавлено через 2 минуты
а еще по хорошему - избавиться от char*
1
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
15.02.2015, 23:12
Цитата Сообщение от kol Посмотреть сообщение
Функции выполняют одну и ту же задачу. Вопрос как сделать шаблон который бы принимал только эти два типа данных(string и char[])?
Для этого не нужен шаблон.
Достаточно двух обычных перегрузок.

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

----------------------------
Не нужно пытаться пролезть в парадные двери через чердак,
если можно просто зайти в парадные двери.
0
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
16.02.2015, 09:27
Цитата Сообщение от hoggy Посмотреть сообщение
Достаточно двух обычных перегрузок
И я о том же.
0
24 / 10 / 5
Регистрация: 30.01.2015
Сообщений: 175
16.02.2015, 15:05  [ТС]
DiffEreD, Можно по подробнее во втором и третьем примере. Ничего на русском про static_assert и is_same не нашел, а с английским плохо.
hoggy, Насчет перегрузок это понятно, но зачем перегружать функцию и создавать лишние 40строчек кода, если можно написать 20 и это будет универсальным решением, другое дело я так делать не умею.
0
 Аватар для DiffEreD
1458 / 795 / 257
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
16.02.2015, 15:30
static_assert - проверка утверждения во время компиляции, если оно ложно, то компиляция на этом месте остановится и выведется сообщение об ошибке, переданное вторым аргументом в static_assert

Проверка идет так:
C++
1
2
3
4
static_assert(   std::is_same<T, std::string>::value // value будет true если Т есть std::string, иначе false
                  || std::is_same<T, const char*>::value // true если Т есть const char*, иначе false
                  || std::is_same<T, char*>::value, // true если Т есть char*, иначе false
                     "NOT A STR_TYPE"); // если соответствий нет - значит компилятор не пропустит код
Добавлено через 1 минуту
std::is_same

Добавлено через 4 минуты
Цитата Сообщение от kol Посмотреть сообщение
но зачем перегружать функцию и создавать лишние 40строчек кода, если можно написать 20 и это будет универсальным решением
Типы string и char* очень сильно отличаються между собой. Не возможно определить одну шаблонную ф-цию для реализации специфических алгоритмов по обработке этих разных типов.
0
24 / 10 / 5
Регистрация: 30.01.2015
Сообщений: 175
16.02.2015, 15:47  [ТС]
DiffEreD, Большое спасибо за разъяснение. У меня правда будет ещё один вопрос.
Можно ли задать пользовательски тип данных с помошью typedef? Например только для чар и стринг...хоять пишу это сообщение и понимаю что говорю глупость.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
16.02.2015, 15:47
Помогаю со студенческими работами здесь

Обработка исключений в классах для пользовательских типов
Здорова господа! Запустил токо класс String тестю и тут у меня вылетело исключение выход за пределы индекса, и программа тупо аварийно...

Шаблон для разных типов
как создать шаблон для функции чтобы мог юзер вводить int, float значение . void VectrUmnVectr() { int n; double res = 0; ...

Приведение пользовательских типов
#include &lt;iostream&gt; using namespace std; class cl { friend cl operator+(cl&amp; s2); public: cl(int d = 0, int c = 0) { ...

Создание пользовательских типов
помогите пожалуйста написать программу. (необходимо написать с применением операторов &quot;printf/scanf&quot;); Сведения об экзамене...

Преобразование пользовательских типов
Добрый день. Суть проблемы такова. Есть 2 класса. Преобразовать через оператор получается. А через конструктор нет. Причем ошибка...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru