Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.88/25: Рейтинг темы: голосов - 25, средняя оценка - 4.88
900 / 477 / 93
Регистрация: 10.06.2014
Сообщений: 2,698
1

Что означает решетка внутри макроса?

10.07.2017, 19:54. Показов 4761. Ответов 17
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Нашёл код, там внутри макроса используются решетки. Что это означает? Если объясните сам код вообще было бы круто!

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
#include <iostream>
 
#define CREATE_MEMBER_DETECTOR(X)                                                   \
template<typename T> class Detect_##X {                                             \
    struct Fallback { int X; };                                                     \
    struct Derived : T, Fallback { };                                               \
                                                                                    \
    template<typename U, U> struct Check;                                           \
                                                                                    \
    typedef char ArrayOfOne[1];                                                     \
    typedef char ArrayOfTwo[2];                                                     \
                                                                                    \
    template<typename U> static ArrayOfOne & func(Check<int Fallback::*, &U::X> *); \
    template<typename U> static ArrayOfTwo & func(...);                             \
  public:                                                                           \
    typedef Detect_##X type;                                                        \
    enum { value = sizeof(func<Derived>(0)) == 2 };                                 \
};
 
CREATE_MEMBER_DETECTOR(first);
CREATE_MEMBER_DETECTOR(second);
 
int main(void)
{
  typedef std::pair<int, double> Pair;
  std::cout << ((Detect_first<Pair>::value && Detect_second<Pair>::value)? "Pair" : "Not Pair");
}
http://rextester.com/SKFM52216
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
10.07.2017, 19:54
Ответы с готовыми решениями:

Что означает слово struct внутри объявления структуры?
Допустим объявляю структуру следующим образом: struct element{ int id; struct element*...

Что означает "Нельзя изменять значение переменной цикла внутри этого цикла"?
Собственно, сама программа. {Дана целочисленная матрица Aij i=1..n,j=1..m (n,m&lt;=100). Найти...

Define внутри макроса
Подкажите возможно ли написать макрос кот. создаст #define? например: #define MACRO(name) ...

Использование списка внутри макроса
Добрый день ! Помогите, что то не могу догадаться как работать с небольшим списком используя его...

17
Заблокирован
10.07.2017, 19:55 2
Цитата Сообщение от Undisputed Посмотреть сообщение
Что это означает?
Конкатенацию токенов. https://gcc.gnu.org/onlinedocs... ation.html
1
900 / 477 / 93
Регистрация: 10.06.2014
Сообщений: 2,698
10.07.2017, 19:58  [ТС] 3
Судя по всему решетка задаёт остаток имени. Но почему именно ##X? Это синтаксис такой или можно и по другому ?
0
What a waste!
1610 / 1302 / 180
Регистрация: 21.04.2012
Сообщений: 2,733
10.07.2017, 20:00 4
# - преобразует идентификатор в строковый литерал.
## - конкатенация.
en.cppreference.com/w/cpp/preprocessor/replace. См. # and ## operators.
1
900 / 477 / 93
Регистрация: 10.06.2014
Сообщений: 2,698
10.07.2017, 20:07  [ТС] 5
daun-autist, gray_fox,
Круто, спасибо!

Попытаюсь разобрать код на основе полученных знаний, но если кто то решит пояснить буду только рад!
0
Заблокирован
10.07.2017, 20:10 6
Undisputed, что тут разбираться?
Раскрытие макроса CREATE_MEMBER_DETECTOR(first); превращается в определение шаблона класса
C++
1
2
3
template<typename T> class Detect_first {
и т.д.
};;
## нужно чтобы токены Detect_ и first были объединены в один токен Detect_first
0
900 / 477 / 93
Регистрация: 10.06.2014
Сообщений: 2,698
10.07.2017, 20:12  [ТС] 7
daun-autist,
Я про логику в коде. Например не понятно зачем там два массива char которые состоят из 1 и 2 элементов
0
What a waste!
1610 / 1302 / 180
Регистрация: 21.04.2012
Сообщений: 2,733
10.07.2017, 20:38 8
Undisputed, данный макрос разворачиватся в type_trait для определения наличия члена класса.
Ещё pre-C++11, сейчас можно и покороче написать.

Добавлено через 9 минут
Цитата Сообщение от Undisputed Посмотреть сообщение
не понятно зачем там два массива char которые состоят из 1 и 2 элементов
Там два шаблона функций. Первый инстанциируется, если у T есть член X. Иначе второй (у функций с элипсисом наименьший приоритет - это fallback). Два массива char нужны для того, что бы понять, какой из этих шаблонов функций инстанциировался (за счёт sizeof).

Добавлено через 13 минут
Сейчас можно использовать специализацию c void_t: http://en.cppreference.com/w/cpp/types/void_t.

Добавлено через 1 минуту
Хотя, конечно, для каждого члена класса и т.д. придётся так же иметь отдельный класс.
1
Заблокирован
10.07.2017, 20:39 9
Цитата Сообщение от Undisputed Посмотреть сообщение
Например не понятно зачем там два массива char которые состоят из 1 и 2 элементов
Для определения того, какой из шаблонов функции func был выбран в func<Derived>(0).

Попытаюсь ниже не соврать.

Если в типе T (в частности, здесь это Pair a.k.a. std::pair<int, double>) есть член X (здесь first или second), то шаблон
C++
1
template<typename U> static ArrayOfOne & func(Check<int Fallback::*, &U::X> *);
не выберется в func<Derived>(0), т.к. будет неясно, какой из Derived::X (Derived::first) имеется в виду в &U::X, будет ambiguity. Но мы знаем, что substitution failure is not an error, поэтому этот шаблон просто удалится из кандидатов и будет выбран второй шаблон.

Если же в типе T нет члена X, то при выборе первого шаблона не возникнет неоднозначности с тем, на какое из полей ссылается U::X.


Цитата Сообщение от gray_fox Посмотреть сообщение
Первый инстанциируется, если у T есть член X.
Правильно. Только наоборот.
2
What a waste!
1610 / 1302 / 180
Регистрация: 21.04.2012
Сообщений: 2,733
10.07.2017, 20:45 10
Цитата Сообщение от daun-autist Посмотреть сообщение
Правильно. Только наоборот.
Да, наоборот.
0
Заблокирован
10.07.2017, 20:48 11
Цитата Сообщение от daun-autist Посмотреть сообщение
неясно, какой из Derived::X (Derived::first) имеется в виду
Я тут неаккуратно написал: будет не ясно, T::X или Fallback::X имеется в виду.

Короче, вы понели.
0
900 / 477 / 93
Регистрация: 10.06.2014
Сообщений: 2,698
10.07.2017, 22:00  [ТС] 12
daun-autist,

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

Но это работает)) видимо я чего то не догоняю

Добавлено через 4 минуты
Помоему шаблон без эллипсиса больше подходит для того чтоб определить есть в классе искомый член или нет
Но раз работает наверное я ошибаюсь...просто параметры этого шаблона визуально выглядят более подходящими
0
Заблокирован
10.07.2017, 22:48 13
Undisputed, я же вроде всё расписал довольно подробно...

Когда в типе T есть член с именем X, то в Derived, унаследованном от Fallback (в котором тоже есть член X) и T, возникают два члена X: T::X и Fallback::X.
И в шаблоне
C++
1
template<typename U> static ArrayOfOne & func(Check<int Fallback::*, &U::X> *);
вызываемом с U = Derived, в U::X = Derived::X возникает неоднозначность с тем, на какой X — T::X и Fallback::X — ссылаются. Из-за этой неоднозначности шаблон исключается из списка кандидатов.
1
900 / 477 / 93
Регистрация: 10.06.2014
Сообщений: 2,698
10.07.2017, 23:05  [ТС] 14
daun-autist,
Вот оно что.
Теперь понятно, спасибо.

Добавлено через 3 минуты
Просто обычно ошибки вроде ambiguous приводят к ошибке компиляции, но в данном случае кандидат на инстанциирование просто отбрасывается.
С этой точки зрения об этом я даже и не задумался
0
Заблокирован
10.07.2017, 23:10 15
Цитата Сообщение от Undisputed Посмотреть сообщение
Просто обычно ошибки вроде ambiguous приводят к ошибке компиляции, но в данном случае кандидат на инстанциирование просто отбрасывается.
Это называется SFINAE.

Добавлено через 1 минуту
Цитата Сообщение от daun-autist Посмотреть сообщение
неоднозначность с тем, на какой X — T::X и Fallback::X — ссылаются.
T::X или Fallback::X
0
dawn artist
12.07.2017, 09:40
  #16

Не по теме:

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

0
116 / 4 / 0
Регистрация: 05.06.2019
Сообщений: 62
30.03.2020, 21:40 17
Не понятно что значит Fallback::* ?
* указатель на тип Fallback? Если да, то где имя указателя? Обычно например пишут int *p, что означает что это указатель на тип int и имя указателя, а здесь как?

C++
1
template<typename U> static ArrayOfOne & func(Check<int Fallback::*, &U::X> *);
0
19409 / 10028 / 2443
Регистрация: 30.01.2014
Сообщений: 17,678
30.03.2020, 21:47 18
Цитата Сообщение от Ivan-88 Посмотреть сообщение
Не понятно что значит Fallback::* ?
Неверно читаете.
Не Fallback::*, а int Fallback::* - это указатель на нестатический член типа int класса Fallback.

Цитата Сообщение от Ivan-88 Посмотреть сообщение
&U::X
Это взятие адреса этого члена.

Цитата Сообщение от Undisputed Посмотреть сообщение
template<typename U, U> struct Check;
typename U - будет int Fallback::*

Цитата Сообщение от Ivan-88 Посмотреть сообщение
где имя указателя?
Вот здесь, оно опущено за ненадобностью:
C++
1
template<typename U, U /*имя указателя*/> struct Check;
1
30.03.2020, 21:47
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
30.03.2020, 21:47
Помогаю со студенческими работами здесь

Подпрограммы (RCALL) внутри макроса
Доброго времени суток! Постараюсь максимально точно изложить суть проблемы, которую я испытываю в...

Выполнение макроса внутри диалогового окна Excel
Доброго времени суток, уважаемые гуру! Подскажите, пожалуйста, можно ли запустить выполнение...

Что означает появление письменности (языка), и что означает реформа письменности (языка)?
Не секрет, что духовность всегда сокрыта в письменности (языке), так высшая стадия развития...

Поясните пожалуйста что означает двоеточие и то что идет после него
В 4 строчке после параметра в скобочках нету &quot;;&quot; или же тела функции, что не сходится с моим...


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

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru