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

шаблоны

31.07.2011, 11:36. Показов 5504. Ответов 61

Студворк — интернет-сервис помощи студентам
возник вопрос, а как можно сделать так, чтобы различные экземпляры шаблона класса вели себя по разному в зависимости от того, что было передано в аргументах - класс или некласс. Приведу пример

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
template<typename T>
class Class {
  private:
 
    template<typename C> bool func(C const& x, C const& y, int C::*)
    {
        return true;
    }
 
    template<typename C> bool func(...)
    {
        return false;
    }
 
  public:
    bool operator()(T const& lhs, T const& rhs)
    {
        return func<T>(lhs, rhs, 0);
    }
};
пример конечно неважный, но суть ясна - в зависимости от того, что подставлять заместо Т этот недофунктор ведёт себя по разному. Пользователь не видит ужасного быдлокода между строками 5-13 и это радует, но не совсем. Я тут подумал может как то присобачить можно этот пример из книжки по шаблонам:
C++
1
2
3
4
5
6
7
8
9
10
11
12
template<typename T>
class IsClassT {
  private:
    typedef char One;
    typedef struct { char a[2]; } Two;
    template<typename C> static One test(int C::*);
 
    template<typename C> static Two test(...);
  public:
    enum { Yes = sizeof(IsClassT<T>::test<T>(0)) == 1 };
    enum { No = !Yes };
};
вдруг я ещё захочу пятьсот классов написать, а такой синтаксис нагоняет тоску... Можно как-то эти Yes и No присобачить заместо int C::*?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
31.07.2011, 11:36
Ответы с готовыми решениями:

«Шаблоны шаблонов» vs «шаблоны с параметрами-шаблонами».
«Шаблоны шаблонов» vs «шаблоны с параметрами-шаблонами». Есть ли разница в этих понятиях? Если есть, то в чём? И где (в каких...

Шаблоны. Плохо понимаемые моменты из книги "Шаблоны С++. Справочник разработчика". (Вандевурд, Джосаттис)
Так как изучаю эту книгу, то в некоторых местах возникают вопросы. Чтобы не плодить много тем, корни у которых одни, решил создать эту...

Помогите писать на С++ через шаблоны. Консуле я писал, но надо писать исползуя шаблоны
В одномерном массиве, состоящем из п вещественных элементов, вычислить: 1) количество элементов массива, равных 0; 2) сумму элементов...

61
101 / 101 / 27
Регистрация: 10.09.2010
Сообщений: 267
31.07.2011, 11:44
а что по твоему не класс?? структуры и стандартные типы???
0
Эксперт С++
 Аватар для grizlik78
2382 / 1666 / 279
Регистрация: 29.05.2011
Сообщений: 3,402
31.07.2011, 11:54
Цитата Сообщение от Overmind024 Посмотреть сообщение
а что по твоему не класс?? структуры и стандартные типы???
Не хочется снова раздувать многостраничное обсуждение, но структура — это класс
0
Эксперт С++
 Аватар для niXman
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
31.07.2011, 12:04
если я тебя правильно понял, то так:
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <iostream>
 
template<typename T>
struct is_pod {
   static const bool value = false;
};
 
template<>
struct is_pod<char> { static const bool value = true; };
template<>
struct is_pod<signed char> { static const bool value = true; };
template<>
struct is_pod<unsigned char> { static const bool value = true; };
template<>
struct is_pod<short> { static const bool value = true; };
template<>
struct is_pod<unsigned short> { static const bool value = true; };
template<>
struct is_pod<int> { static const bool value = true; };
template<>
struct is_pod<unsigned int> { static const bool value = true; };
template<>
struct is_pod<long> { static const bool value = true; };
template<>
struct is_pod<unsigned long> { static const bool value = true; };
template<>
struct is_pod<long long> { static const bool value = true; };
template<>
struct is_pod<unsigned long long> { static const bool value = true; };
 
template<bool ok, typename T>
struct real_func {
   static bool apply() {
      std::cout << __PRETTY_FUNCTION__ << std::endl;
      return ok;
   }
};
 
// ручная специализация для POD`ов
template<typename T>
struct real_func<true, T> {
   static bool apply() {
      std::cout << __PRETTY_FUNCTION__ << std::endl;
      return true;
   }
};
 
int main() {
   std::cout << std::boolalpha << real_func<is_pod<char>::value, char>::apply() << std::endl;
   std::cout << std::boolalpha << real_func<is_pod<std::ostream>::value, std::ostream>::apply() << std::endl;
}
http://liveworkspace.org/code/... e00c4a332d

зы
тема вообще-то не для раздела новичков

Добавлено через 42 секунды
Цитата Сообщение от grizlik78 Посмотреть сообщение
но структура — это класс
угу. в с++ иначе быть не может.

Добавлено через 50 секунд
LosAngeles, надеюсь как использовать этот type_traits сам разберешься?

Добавлено через 51 секунду
и вообще-то, для этого написано огромное кол-шаблонов на все случаи жизни: http://www.boost.org/doc/libs/... index.html
2
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
31.07.2011, 12:15
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
 
struct mystruct {
};
 
class myclass {
    myclass(int);
};
 
int main()
{
    std::cout << std::boolalpha << std::is_pod<mystruct>().value << '\n'
              << std::boolalpha << std::is_pod<myclass>().value << '\n'
              << std::boolalpha << std::is_class<mystruct>().value << '\n'
              << std::boolalpha << std::is_class<myclass>().value << '\n';
    return 0;
}
0
Эксперт С++
 Аватар для grizlik78
2382 / 1666 / 279
Регистрация: 29.05.2011
Сообщений: 3,402
31.07.2011, 12:17
Maxwe11, ну а POD-то тут к чему? Убери конструктор из класса и добавь к структуре, и вывод для is_pod изменится на противоположный.
0
Эксперт С++
 Аватар для niXman
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
31.07.2011, 12:18
Цитата Сообщение от Maxwe11 Посмотреть сообщение
std::is_class<myclass>()
зачем ты создаешь объекты compile-time шаблонов?
0
Заблокирован
31.07.2011, 12:22  [ТС]
Цитата Сообщение от niXman Посмотреть сообщение
если я тебя правильно понял, то так:
да что-то типа того, но я надеялся как то автоматизировать процесс.
я как то так хотел сделать
C++
1
2
template<typename T, bool b = IsClassT<T>::Yes >
class Class;
и написать потом всего две специализации, но видимо не катит, потому что b зависит от Т. Да и все варианты не предусмотришь, как быть если мне понадобятся char* int* double****? Придётся ещё писать для них специализации. Понятно, что задача абстрактная, врядли мне это понадобится. Все эти is_pod и is_class хороши но я хочу именно на этапе компиляции отрезать не нужные ветки кода, я ещё подумал про #if\#else но ничего у меня не получилось с ними(
0
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
31.07.2011, 12:22
Цитата Сообщение от grizlik78 Посмотреть сообщение
Убери конструктор из класса и добавь к структуре, и вывод изменится на противоположный.
я и не спорю

Цитата Сообщение от niXman Посмотреть сообщение
зачем ты создаешь объекты compile-time шаблонов?
а как иначе?
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
31.07.2011, 12:27
Цитата Сообщение от LosAngeles Посмотреть сообщение
да что-то типа того, но я надеялся как то автоматизировать процесс
Прежде, чем что-то автоматизировать, поставь внятно вопрос. Если я правильно понял (да и остальные тоже), то тебе нужно разделить на "скалярные типы" и "составные типы" или чего?
0
Эксперт С++
 Аватар для niXman
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
31.07.2011, 12:27
Цитата Сообщение от LosAngeles Посмотреть сообщение
я надеялся как то автоматизировать процесс.
специализации тебе придется писать руками. а дальше на основе их проксируй необходимую реализацию.

Цитата Сообщение от LosAngeles Посмотреть сообщение
как быть если мне понадобятся char* int* double****?
тоже специализировать руками

Цитата Сообщение от Maxwe11 Посмотреть сообщение
а как иначе?
так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
 
struct mystruct {
};
 
class myclass {
};
 
int main()
{
    std::cout << std::boolalpha << std::is_pod<mystruct>::value << std::endl
              << std::boolalpha << std::is_pod<myclass>::value << std::endl
              << std::boolalpha << std::is_class<mystruct>::value << std::endl
              << std::boolalpha << std::is_class<myclass>::value << std::endl;
    return 0;
}
http://liveworkspace.org/code/... c6fc62e33c

т.к. "результат" этих шаблонов известен еще на стадии компиляции.
2
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
31.07.2011, 12:30
Цитата Сообщение от Evg Посмотреть сообщение
Если я правильно понял (да и остальные тоже), то тебе нужно разделить на "скалярные типы" и "составные типы" или чего?
Если оно так, то я бы написал два разных шаблона: один для скалярных типов, один для составных. А в месте использования, там где я знаю, с каким типом работаю, использовал бы первый или второй. Это не очень красиво, но технически, как мне кажется, проще, чем работать с кучей специализаций, особенно если шаблон будет постоянно развиваться
1
Эксперт С++
 Аватар для niXman
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
31.07.2011, 12:33
специализация для указателей:
C++
1
2
3
4
5
6
7
8
9
template<class T>
struct is_pointer {
   static const bool value = false;
};
 
template<class T>
struct is_pointer<T*> {
   static const bool value = true;
};
и комбинируй вместе с is_pod<>, тогда сможешь определить, является ли указатель, указателем на под.
1
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
31.07.2011, 12:34
Цитата Сообщение от niXman Посмотреть сообщение
т.к. "результат" этих шаблонов известен еще на стадии компиляции.
про это я в курсе, и даже сначала так и написал но студия меня чего-то непоняла)
0
Эксперт С++
 Аватар для niXman
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
31.07.2011, 12:35
Цитата Сообщение от Evg Посмотреть сообщение
как мне кажется, проще, чем работать с кучей специализаций
я и не предлагал кучу конечных специализаций. их должно быть две. но чтоб компилятору объяснить кто POD а кто нет, придется руками написать специализации шаблона is_pod<> для POD`ов.
0
Заблокирован
31.07.2011, 12:38  [ТС]
Цитата Сообщение от niXman Посмотреть сообщение
тоже специализировать руками
жаль, я ещё попытался добавить операцию деления Ну то есть Yes это же единица, а No это 0, я думал тогда компилятор выберет наиболее подходящий шаблон, в котором деления на ноль нету, однако потом вычитал, что SFINAE на неправильные вычисления не распространяется, а жаль((
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
31.07.2011, 12:41
Цитата Сообщение от niXman Посмотреть сообщение
я и не предлагал кучу конечных специализаций. их должно быть две. но чтоб компилятору объяснить кто POD а кто нет, придется руками написать специализации шаблона is_pod<> для POD`ов.
А... понятно...
В итоге получается что можно сделать и так и сяк, один фиг оба решения по сути череж..ные
0
Эксперт С++
 Аватар для niXman
3211 / 1459 / 74
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
31.07.2011, 12:43
Цитата Сообщение от Evg Посмотреть сообщение
череж..ные
да. так и живем
все равно, с++ лучший ЯП в мире
1
101 / 101 / 27
Регистрация: 10.09.2010
Сообщений: 267
31.07.2011, 13:16
Можно и без шаблонов

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
#include <iostream>
#include <typeinfo>
 
template<class T>
struct IsClass 
{
    bool operator() ()
    {
        const char* str = typeid(T).name();
        return (((strstr(str,"class") != NULL) || (strstr(str,"struct") != NULL)) && ( *(str+strlen(str) - 1) != '*'));
    }
};
 
int main()
{
    std::cout << std::boolalpha << IsClass<int>()() << std::endl;
    std::cout << std::boolalpha << IsClass<std::ostream>()() << std::endl;
    std::cout << std::boolalpha << IsClass<std::ostream*>()() << std::endl;
 
    std::cin.get();
    std::cin.get();
 
    return 0;
}
0
Эксперт С++
 Аватар для grizlik78
2382 / 1666 / 279
Регистрация: 29.05.2011
Сообщений: 3,402
31.07.2011, 13:22
Без шаблонов не интересно.
Мне кажется, изначально хотелось чего-то вроде этого:
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <iostream>
 
template<typename T>
class IsClassT {
  private:
    typedef char One;
    typedef struct { char a[2]; } Two;
    template<typename C> static One test(int C::*);
    
    template<typename C> static Two test(...);
  public:
    enum { Yes = sizeof(IsClassT<T>::test<T>(0)) == 1 };
    enum { No = !Yes };
};
 
template<typename T>
class Class {
  private:
 
    template <typename C, bool>
    struct Internal
    {
        static
        bool func(C const& x, C const& y)
        {
            return true;
        }
    };
 
    template <typename C>
    struct Internal<C, false>
    {
        static
        bool func(C const& x, C const& y)
        {
            return false;
        }
    };
 
  public:
    bool operator()(T const& lhs, T const& rhs)
    {
        return Internal<T, IsClassT<T>::Yes>::func(lhs, rhs);
    }
};
 
 
class A
{
};
 
int main()
{
    Class<A> c1;
    Class<int> c2;
 
    A a1, a2;
    int i1, i2;
 
    std::cout << "result with class A: " << std::boolalpha << c1(a1, a2) << std::endl;
    std::cout << "result with int: " << std::boolalpha << c2(i1, i2) << std::endl;
 
    return 0;
}
Если бы была разрешена частичная специализация шаблонов-функций, то внутренняя структура, наверное, не понадобилась бы.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
31.07.2011, 13:22
Помогаю со студенческими работами здесь

Шаблоны
Добрый день. Не могли бы объяснить вот этот вопрос: Допускают ли шаблоны вложенность описания?

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

Шаблоны
ругается на строку &quot;friend class List&lt;T&gt;;&quot;, вот что пишет: 1&gt;c:\users\slava\documents\visual studio...

шаблоны в си++
кто может сказать где прблема? List.h #ifndef LIST_H #define LIST_H #include&lt;iostream&gt; #include&lt;ostream&gt; ...

Шаблоны
Здравствуйте не объясните новичку пару аспектов про шаблоны 1)Зачем они нужны 2)Преимущества 3)Синтаксис 4)Маленький примерчик


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. На мобильном - сканируйте QR-код. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
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. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru