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

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

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

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

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
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
10.07.2017, 19:54
Ответы с готовыми решениями:

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

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

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

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

Попытаюсь разобрать код на основе полученных знаний, но если кто то решит пояснить буду только рад!
0
Заблокирован
10.07.2017, 20:10
Undisputed, что тут разбираться?
Раскрытие макроса CREATE_MEMBER_DETECTOR(first); превращается в определение шаблона класса
C++
1
2
3
template<typename T> class Detect_first {
и т.д.
};;
## нужно чтобы токены Detect_ и first были объединены в один токен Detect_first
0
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
10.07.2017, 20:12  [ТС]
daun-autist,
Я про логику в коде. Например не понятно зачем там два массива char которые состоят из 1 и 2 элементов
0
What a waste!
 Аватар для gray_fox
1610 / 1302 / 180
Регистрация: 21.04.2012
Сообщений: 2,733
10.07.2017, 20:38
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
Цитата Сообщение от 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!
 Аватар для gray_fox
1610 / 1302 / 180
Регистрация: 21.04.2012
Сообщений: 2,733
10.07.2017, 20:45
Цитата Сообщение от daun-autist Посмотреть сообщение
Правильно. Только наоборот.
Да, наоборот.
0
Заблокирован
10.07.2017, 20:48
Цитата Сообщение от daun-autist Посмотреть сообщение
неясно, какой из Derived::X (Derived::first) имеется в виду
Я тут неаккуратно написал: будет не ясно, T::X или Fallback::X имеется в виду.

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

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

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

Добавлено через 4 минуты
Помоему шаблон без эллипсиса больше подходит для того чтоб определить есть в классе искомый член или нет
Но раз работает наверное я ошибаюсь...просто параметры этого шаблона визуально выглядят более подходящими
0
Заблокирован
10.07.2017, 22:48
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
901 / 478 / 93
Регистрация: 10.06.2014
Сообщений: 2,700
10.07.2017, 23:05  [ТС]
daun-autist,
Вот оно что.
Теперь понятно, спасибо.

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

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

Не по теме:

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

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

C++
1
template<typename U> static ArrayOfOne & func(Check<int Fallback::*, &U::X> *);
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
30.03.2020, 21:47
Цитата Сообщение от 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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
30.03.2020, 21:47
Помогаю со студенческими работами здесь

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

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Новые блоги и статьи
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
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