Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 24, средняя оценка - 4.79
LosAngeles
Заблокирован
#1

шаблоны - C++

31.07.2011, 11:36. Просмотров 3025. Ответов 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
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
31.07.2011, 11:36
Здравствуйте! Я подобрал для вас темы с ответами на вопрос шаблоны (C++):

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

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

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

Шаблоны C++ - C++
Написал template на С++, но он нифига не компилица, пишет мол типа не могу string в int преобразовать в строчке int out_param = (int)param;...

Шаблоны - C++
Я разбираюсь с ООП в С++ и застрял на шаблонах, будьте добры приведите пример кода, к примеру там.... вес машины и шаблон,(ну вообщем на...

Шаблоны - C++
// ConsoleApplication176.cpp : Defines the entry point for the console application. // template&lt;class type&gt; struct link { type...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Overmind024
99 / 99 / 6
Регистрация: 10.09.2010
Сообщений: 267
31.07.2011, 11:44 #2
а что по твоему не класс?? структуры и стандартные типы???
0
grizlik78
Эксперт С++
1913 / 1445 / 113
Регистрация: 29.05.2011
Сообщений: 3,001
31.07.2011, 11:54 #3
Цитата Сообщение от Overmind024 Посмотреть сообщение
а что по твоему не класс?? структуры и стандартные типы???
Не хочется снова раздувать многостраничное обсуждение, но структура — это класс
0
niXman
Эксперт C++
3137 / 1449 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
31.07.2011, 12:04 #4
если я тебя правильно понял, то так:
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/8553d9...f4ace00c4a332d

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

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

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

Добавлено через 51 секунду
и вообще-то, для этого написано огромное кол-шаблонов на все случаи жизни: http://www.boost.org/doc/libs/1_47_0...tml/index.html
2
Jupiter
Каратель
Эксперт С++
6554 / 3975 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
31.07.2011, 12:15 #5
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
Эксперт С++
1913 / 1445 / 113
Регистрация: 29.05.2011
Сообщений: 3,001
31.07.2011, 12:17 #6
Maxwe11, ну а POD-то тут к чему? Убери конструктор из класса и добавь к структуре, и вывод для is_pod изменится на противоположный.
0
niXman
Эксперт C++
3137 / 1449 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
31.07.2011, 12:18 #7
Цитата Сообщение от Maxwe11 Посмотреть сообщение
std::is_class<myclass>()
зачем ты создаешь объекты compile-time шаблонов?
0
LosAngeles
Заблокирован
31.07.2011, 12:22  [ТС] #8
Цитата Сообщение от 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
Jupiter
Каратель
Эксперт С++
6554 / 3975 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
31.07.2011, 12:22 #9
Цитата Сообщение от grizlik78 Посмотреть сообщение
Убери конструктор из класса и добавь к структуре, и вывод изменится на противоположный.
я и не спорю

Цитата Сообщение от niXman Посмотреть сообщение
зачем ты создаешь объекты compile-time шаблонов?
а как иначе?
0
Evg
Эксперт CАвтор FAQ
17823 / 6033 / 388
Регистрация: 30.03.2009
Сообщений: 16,563
Записей в блоге: 26
31.07.2011, 12:27 #10
Цитата Сообщение от LosAngeles Посмотреть сообщение
да что-то типа того, но я надеялся как то автоматизировать процесс
Прежде, чем что-то автоматизировать, поставь внятно вопрос. Если я правильно понял (да и остальные тоже), то тебе нужно разделить на "скалярные типы" и "составные типы" или чего?
0
niXman
Эксперт C++
3137 / 1449 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
31.07.2011, 12:27 #11
Цитата Сообщение от 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/611cf2...f9f0c6fc62e33c

т.к. "результат" этих шаблонов известен еще на стадии компиляции.
2
Evg
Эксперт CАвтор FAQ
17823 / 6033 / 388
Регистрация: 30.03.2009
Сообщений: 16,563
Записей в блоге: 26
31.07.2011, 12:30 #12
Цитата Сообщение от Evg Посмотреть сообщение
Если я правильно понял (да и остальные тоже), то тебе нужно разделить на "скалярные типы" и "составные типы" или чего?
Если оно так, то я бы написал два разных шаблона: один для скалярных типов, один для составных. А в месте использования, там где я знаю, с каким типом работаю, использовал бы первый или второй. Это не очень красиво, но технически, как мне кажется, проще, чем работать с кучей специализаций, особенно если шаблон будет постоянно развиваться
1
niXman
Эксперт C++
3137 / 1449 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
31.07.2011, 12:33 #13
специализация для указателей:
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
Jupiter
Каратель
Эксперт С++
6554 / 3975 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
31.07.2011, 12:34 #14
Цитата Сообщение от niXman Посмотреть сообщение
т.к. "результат" этих шаблонов известен еще на стадии компиляции.
про это я в курсе, и даже сначала так и написал но студия меня чего-то непоняла)
0
niXman
Эксперт C++
3137 / 1449 / 49
Регистрация: 09.08.2009
Сообщений: 3,441
Записей в блоге: 2
31.07.2011, 12:35 #15
Цитата Сообщение от Evg Посмотреть сообщение
как мне кажется, проще, чем работать с кучей специализаций
я и не предлагал кучу конечных специализаций. их должно быть две. но чтоб компилятору объяснить кто POD а кто нет, придется руками написать специализации шаблона is_pod<> для POD`ов.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
31.07.2011, 12:35
Привет! Вот еще темы с ответами:

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

Шаблоны - C++
Когда разделяю реализацию и прототип шаблонной в функции по разным файлам (*.h и *.cpp) происходит ошибка линковки... Я так понимаю, делать...

Шаблоны С++ - C++
template &lt;typename T_sizeCapacity&gt; class SomeClass { public: T_sizeCacity size; }; Как сделать чтобы T_sizeCapacity мог быть...

Шаблоны - C++
Не пойму что я неправильно делаю. Как не переделывал, всё равно не получалось. Может кто сможет чем помочь. А задача следующая-надо было...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
31.07.2011, 12:35
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru