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

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

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

непонятная конструкция, шаблоны - C++

30.07.2011, 17:28. Просмотров 2228. Ответов 38
Метки нет (Все метки)

столкнулся со странной конструкцией
C++
1
template<typename C> static One test(int C::*);
в
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 };
};
в упор не понимаю, что значит int C::*
видел объяснения на русском, на инглише, что это мол какой-то указатель на член, всё равно не догоняю. Может кто-нибудь доходчиво объяснить или хотя привести примеры зачем это нужно ну кроме как здесь? Всё остальное понятно, мне бы этот момент главное прояснить. Заранее спасибо
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.07.2011, 17:28
Я подобрал для вас темы с готовыми решениями и ответами на вопрос непонятная конструкция, шаблоны (C++):

Шаблоны классов: непонятная ошибка в одном из методов класса - C++
Задача создать шаблон двоичного дерева поиска. В методе удаления узла IntelliSense выдает ошибку: ссылается на if и пишет: &quot;требуется...

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

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

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

Непонятная конструкция в C++ - C++
Наткнулся на конструкцию, для которой g++ работает не так, как компилятор безо всяких расширений (в мойм случае это Sun CC). template...

конструкция - C++
Доброго времени суток, с с++ мало знаком не могли бы пояснить некоторые моменты кода. #include &lt;math.h&gt; void tred2(float **a,...

38
Kastaneda
Jesus loves me
Эксперт С++
4749 / 2953 / 242
Регистрация: 12.12.2009
Сообщений: 7,493
Записей в блоге: 2
Завершенные тесты: 1
30.07.2011, 22:08 #16
Цитата Сообщение от LosAngeles Посмотреть сообщение
а что тогда можно присвоить р?
Сижу, методом тыка пытаюсь определить - это вообще что?
Арифметические операции к этому p не применяются (ошибка компиляции), оператор разыменования указателя тоже. Присвоить какое-то значение ему невозможно, если вывести это p, то выводится просто 1. Пробую вызывать ф-цию по-разному, не указатель на int, не указатель на функцию типа int(*)() в качестве аргумента неприемлемы (ошибка компиляции). Но сама строка:
C++
1
int C::*p;
компилируется нормально. Вообще странно.
P.S. у меня C - это просто класс.

Добавлено через 2 минуты
Да, оператор () тоже неподходит...

Добавлено через 45 минут
LosAngeles, вот нашел в википедии:
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
  class MyClass
  {
  public:
    int a;
  };
 
  template< class T >
  T& IncrementIntegerElement( int T::* Element, T& Object )
  {
    Object.*Element += 1;
    return Object;
  }
 
  template< class T >
  T IncrementMyClassElement( T MyClass::* Element, MyClass& Object )
  {
    Object.*Element += 1;
    return Object.*Element;
  }
 
  MyClass Obj;
  int n;
 
  n = ( IncrementIntegerElement( &MyClass::a, Obj ) ).a;
  n = IncrementMyClassElement( &MyClass::a, Obj );
Как и предполагалось, это просто указатель на член класса типа int, просто похоже подобная конструкция используется только с шаблонами (с простым классом некомпилируется).
1
Bers
Заблокирован
31.07.2011, 06:17 #17
Цитата Сообщение от Deviaphan Посмотреть сообщение
Только вот у ТС отсутствует список аргументов, при объявлении указателя на метод... Разве так можно?
2008 студия грязно выругалась.

А так, вапще, указатель на метод мне видится неким фейлом.
Попытка заюзать ООП в качестве функционального ЯП
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1306 / 1221 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
31.07.2011, 07:04 #18
Цитата Сообщение от Bers Посмотреть сообщение
А так, вапще, указатель на метод мне видится неким фейлом.
Попытка заюзать ООП в качестве функционального ЯП
Не, не фэйл. Порекомендую ещё раз прочесть Александреску (если после прошлой рекомендации ещё не успели прочитать.) ) про функциональные объекты.


Цитата Сообщение от Kastaneda Посмотреть сообщение
Как и предполагалось, это просто указатель на член класса типа int,
Вероятно, так и есть. Но смысл действа не ясен. Почему там просто указатель на int не передаётся? Ничё не понятно... Если кто понял сакральный смысл этого действа, разъясните тугодуму, плиз.)
0
LosAngeles
Заблокирован
31.07.2011, 07:15  [ТС] #19
если указатель на инт передавать, то первый вариант будет компилироваться всегда вне зависимости от Т вроде как
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1306 / 1221 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
31.07.2011, 07:19 #20
Цитата Сообщение от LosAngeles Посмотреть сообщение
если указатель на инт передавать
Для второго варианта, указатель на Т передать.)
0
LosAngeles
Заблокирован
31.07.2011, 07:25  [ТС] #21
туплю наверно. Не понимаю ты о чём?
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1306 / 1221 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
31.07.2011, 07:36 #22
Цитата Сообщение от LosAngeles Посмотреть сообщение
туплю наверно. Не понимаю ты о чём?
Почему бы не передавать указатель на шаблонный тип Т, вместо указателя на шаблонное поле Т класса С? Т.е. я просто не могу понять разницы, кроме более сложной и запутанной записи. Хочу, чтобы мне объяснили разницу.)

Добавлено через 2 минуты
Т.е. я вообще смысла понять не могу. С методом понятно, я передал указатель на метод и вызываю его для различных объектов. Как-бы настройка поведения. Но зачем это делать с полем? Т.е. можно передать смещение поля в классе, а потом обращаться к этому полю для всех объектов. Это понятно. Но зачем???
0
LosAngeles
Заблокирован
31.07.2011, 07:48  [ТС] #23
имеешь ввиду что это лишние template<typename C>? я тоже задался вопросом нафиг, попытался убрать, но компилятор ломанулся инстанцировать первый вариант и для инт. Впринципе логично, в объявлениях компилятор должен подставить Т, но в случае с интом это не получается. А если методы делать шаблонными, то он доходит до 10 строки и только тогда ломится подставлять один вариантов и подставляет наиболее подходящий
0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1306 / 1221 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
31.07.2011, 07:49 #24
Я имею в виду:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
 template< class T >
  T& IncrementIntegerElement( int * Element )
  {
   *Element += 1;
    return Object;
  }
 
  template< class T >
  T IncrementMyClassElement( T * Element )
  {
   *Element += 1;
    return *Element;
  }
0
LosAngeles
Заблокирован
31.07.2011, 08:06  [ТС] #25
вобщем я не понимаю что ты хочешь сделать, наверно ValeryLaptev или Kastaneda придут и разберутся
0
Kastaneda
Jesus loves me
Эксперт С++
4749 / 2953 / 242
Регистрация: 12.12.2009
Сообщений: 7,493
Записей в блоге: 2
Завершенные тесты: 1
31.07.2011, 09:38 #26
Так:
C++
1
 template<typename C> static One test(int C::*);
мы получаем тип С, который очевидно потребуется в этой функции (можно создать объект С, можно вызвать статичную функцию из класса С, можно еще что-нибудь).
А так:
C++
1
2
3
4
 template<typename C> static One test(C *elem);
 
//или так
template<typename C> static One test(int *elem);
у нас не будет информации о классе, к которому относится переменная elem.

Вобщем подобная запись может понадобиться, если нам зачем-то нужен класс-владелец передоваемого члена.

Не по теме:

это единственное адекватное объяснение, которое пришло мне в голову

0
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1306 / 1221 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
31.07.2011, 10:06 #27
Цитата Сообщение от Kastaneda Посмотреть сообщение
у нас не будет информации о классе, к которому относится переменная elem.
Вобщем подобная запись может понадобиться, если нам зачем-то нужен класс-владелец передоваемого члена.
Так вот в этом и вопрос! Переменную можно отредактировать просто передав. Если передан объект класса, то и переменную можно через объект получить.
Т.е. бессмыслица полная.(
0
Kastaneda
Jesus loves me
Эксперт С++
4749 / 2953 / 242
Регистрация: 12.12.2009
Сообщений: 7,493
Записей в блоге: 2
Завершенные тесты: 1
31.07.2011, 10:17 #28
Ну С++ - язык богатых возможностей) Без реализации функции сложно сказать зачем понадобилась именно такая запись. Как вариант - передаем статичный член (не имея при этом созданного объекта), а внутри вызываем статичную функцию.
0
LosAngeles
Заблокирован
31.07.2011, 10:31  [ТС] #29
пример же в шапке есть зачем это нужно. Если есть хотя бы одна ситуация, где можно применить некую конструкцию, значит она небесполезна?
0
ValeryLaptev
Эксперт С++
1048 / 827 / 48
Регистрация: 30.04.2011
Сообщений: 1,659
31.07.2011, 10:41 #30
Цитата Сообщение от LosAngeles Посмотреть сообщение
столкнулся со странной конструкцией
C++
1
template<typename C> static One test(int C::*);
в
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 };
};
в упор не понимаю, что значит int C::*
видел объяснения на русском, на инглише, что это мол какой-то указатель на член, всё равно не догоняю. Может кто-нибудь доходчиво объяснить или хотя привести примеры зачем это нужно ну кроме как здесь? Всё остальное понятно, мне бы этот момент главное прояснить. Заранее спасибо
Наконец-то я понял, о чем речь. Пример этот - шаблон для определения на этапе компиляции, является ли тип T классом.
Объяснить, как работает - сложно. Надо медитировать на SFINAE.
Но суть в том, что при инстанцировании
C++
1
enum { Yes = sizeof(IsClassT<T>::test<T>(0)) == 1 };
для класса инстанцируется One test, а для не класса - Two test именно потому, что у класса есть элементы, а у не класса - элементов нет.
1
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
31.07.2011, 10:41
Привет! Вот еще темы с ответами:

Конструкция - C++
ребят помогите разобрать конструкцию вида (ah==72)?k--:k; знаю что чтото логическое но вспомнить немогу:)

Конструкция if.. - C++
Помогите пожалуйста довести задачу до конца! Дано натуральное число N. Если оно делится на 4, вывести на экран ответ N=4k (где k –...

Циклическая конструкция - C++
Не могу составить цикл для S = cos1*(cos1 + cos 2) * ... *(cos1+ cos 2 + ... + cos n)

Не работает конструкция с new - C++
char**ex=new char*; for(i=0;i&lt;n;i++) ex=new char; for(i=0;i&lt;n;i++) cin&gt;&gt;ex; почему не работает


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

Или воспользуйтесь поиском по форуму:
30
Ответ Создать тему
Опции темы

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