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

шаблоны

31.07.2011, 11:36. Показов 5418. Ответов 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
Ответ Создать тему
Новые блоги и статьи
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США. Нашел на реддите интересную статью под названием «Кто-нибудь знает, где получить бесплатный компьютер или. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru