С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.70/40: Рейтинг темы: голосов - 40, средняя оценка - 4.70
techpriest
 Аватар для Mirmik
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180

Имитация typeof в C/C++ коде

07.01.2016, 23:02. Показов 8436. Ответов 8
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Можно ли считать, что следующие макросы полностью имитируют typeof через decltypeof и в случае подключения хеадера компилятором С и в случае подключения его компилятором С++?

Или в чем-то поведение будет отличаться?
C++
1
2
3
4
5
6
7
#ifdef __cplusplus
#define __if_C_if_CXX(c, cxx) cxx
#else
#define __if_C_if_CXX(c, cxx) c 
#endif
 
#define decltypeof(a) __if_C_if_CXX(typeof(a), std::remove_reference<decltype(a)>::type)
Добавлено через 6 минут
То есть, задача такова. Я хочу подключать один хеадер и в С и С++ и быть уверенным, что поведение этого самого decltypeof будет совершенно идентичным в обоих случаях.

Добавлено через 2 часа 40 минут
upp
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
07.01.2016, 23:02
Ответы с готовыми решениями:

Typeof
В вижуал не определяется идентификатор typeof. Срочно нужно решить проблему с исправлением этой строчки: struct Consume *ap =...

Decltype и typeof
Товарищи. Возникла проблема с пониманием std++11. Насколько я понимаю typeof более не поддерживается. Сегодня познакомился с...

Имитация нажатия кнопки мыши через процедуру в коде
Есть типичная процедура OnMouseDown: procedure TForm1.IMD(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y:...

8
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
08.01.2016, 00:13
Цитата Сообщение от Mirmik Посмотреть сообщение
Или в чем-то поведение будет отличаться?
ну, например, версия с++ не всегда будет работать.

достаточное отличие?

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
#ifdef __cplusplus
    #define __if_C_if_CXX(c, cxx) cxx
#else
    #define __if_C_if_CXX(c, cxx) c 
#endif
 
#define decltypeof(a) __if_C_if_CXX(typeof(a), std::remove_reference<decltype(a)>::type)
 
 
#include <iostream>
 
template<class T>
T foo(T&& a)
{
    decltypeof(a) val;
    return val;
}
 
int main()
{
    std::cout << "Hello, world!\n";
    
    foo(10);
}

source_file.cpp: In function ‘T foo(T&&)’:
source_file.cpp:9:48: error: need ‘typename’ before ‘std::remove_reference<decltype (a)>::type’ because ‘std::remove_reference<decltype (a)>’ is a dependent scope
#define decltypeof(a) __if_C_if_CXX(typeof(a), std::remove_reference<decltype(a)>::type )
1
techpriest
 Аватар для Mirmik
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
08.01.2016, 01:20  [ТС]
Отлично!

А если вот так:


C++
1
#define decltypeof(a) __if_C_if_CXX(typeof(a), typename std::remove_reference<decltype(a)>::type)
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
08.01.2016, 04:02
Цитата Сообщение от Mirmik Посмотреть сообщение
А если вот так:
тогда оно не будет работать без шаблонов:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#ifdef __cplusplus
    #define __if_C_if_CXX(c, cxx) cxx
#else
    #define __if_C_if_CXX(c, cxx) c 
#endif
 
#define decltypeof(a) __if_C_if_CXX(typeof(a), typename std::remove_reference<decltype(a)>::type)
 
 
#include <iostream>
 
int foo(int a)
{
    decltypeof(a) val;
    return val;
}
 
int main()
{
    std::cout << "Hello, world!\n";
    
    foo(10);
}
source_file.cpp(14): error C2899: typename cannot be used outside a template declaration
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
08.01.2016, 17:09
Цитата Сообщение от hoggy Посмотреть сообщение
тогда оно не будет работать без шаблонов
Справедливости ради, эта ошибка корректна только для С++03.
14.6/5
The keyword typename shall be applied only to qualified names, but those names need not be dependent. The keyword typename shall be used only in contexts in which dependent names can be used. This includes template declarations and definitions but excludes explicit specialization declarations and explicit instantiation declarations.
В С++11 было принято следющее:
http://www.open-std.org/jtc1/s... s.html#382
Выдержка из измененного 14.6/5:
A qualified name used as the name in a mem-initializer-id, a base-specifier, or an elaborated-type-specifier is implicitly assumed to name a type, without the use of the typename keyword. In a nested-name-specifier that immediately contains a nested-name-specifier that depends on a template parameter, the identifier or simple-template-id is implicitly assumed to name a type, without the use of the typename keyword. [ Note: The typename keyword is not permitted by the syntax of these constructs. — end note ]
Таким образом, в С++11 код с typename вне шаблона, наподобие как в примере выше, разрешен. Однако запрещен подобный код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#ifdef __cplusplus
    #define __if_C_if_CXX(c, cxx) cxx
#else
    #define __if_C_if_CXX(c, cxx) c 
#endif
 
#define decltypeof(a) __if_C_if_CXX(typeof(a), typename std::remove_reference<decltype(a)>::type)
  
#include <iostream>
 
struct C {} c;
 
class A : decltypeof(c) // base-specifier
{
};
 
int main()
{
}
http://rextester.com/NQB54372
Кроме того, автору нужно наверное подумать, как быть с C++03. Там нет decltype и std::remove_reference. А в VS нет typeof.
Часть проблем можно снять так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#if defined(__cplusplus) && (__cplusplus > 199711L || defined(_MSC_VER))
    #define __if_C_if_CXX(c, cxx) cxx
#else
    #define __if_C_if_CXX(c, cxx) c 
#endif
 
#ifndef _MSC_VER
    #define TYPENAME_SPEC typename
#else
    #define TYPENAME_SPEC
#endif
 
#define decltypeof(a) \
    __if_C_if_CXX(typeof(a), TYPENAME_SPEC std::remove_reference<decltype(a)>::type)
Но не все. В общем случае задача не решается, как мне кажется.
0
techpriest
 Аватар для Mirmik
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
09.01.2016, 16:33  [ТС]
DrOffset Большое спасибо за подробный анализ 0_о.
Я и не знал, что всё настолько сложно.

Моя задача всё-же несколько по уже. Я старательно ограничиваюсь g++ и считаю, что могу позволить себе не закладываться на с++03, хотя, конечно, было бы неплохо поддержать и его.

Проблема, приведенная тут:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#ifdef __cplusplus
    #define __if_C_if_CXX(c, cxx) cxx
#else
    #define __if_C_if_CXX(c, cxx) c 
#endif
 
#define decltypeof(a) __if_C_if_CXX(typeof(a), typename std::remove_reference<decltype(a)>::type)
  
#include <iostream>
 
struct C {} c;
 
class A : decltypeof(c) // base-specifier
{
};
 
int main()
{
}
Неактуальна по постановке задачи. В языке С нет классов. А значит и в рамках задач, на которые расчитан данный макрос их можно не рассматривать.

Добавлено через 7 минут
PS. Что такое VS?
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
09.01.2016, 16:43
Цитата Сообщение от Mirmik Посмотреть сообщение
В языке С нет классов. А значит и в рамках задач, на которые расчитан данный макрос их можно не рассматривать.
В таком случае можно не рассматривать и шаблоны, т.к. в языке С нет их тоже.
Правда мне видится здесь некоторое противоречие, объясню:
У нас есть единый h-ник, который используется как в С, так и в С++ коде. Кто собственно мешает в С коде использовать его как принято в С (естественно без классов и шаблонов), а в коде на С++, так как принято в С++, т.е. и с классами, и с шаблонами. Вообще говоря, проблемы, которые мы здесь озвучили, касаются только С++ и возникнут только при использовании в С++. Основная сложность в том, что нельзя сделать такой единый макрос, который анализировал бы варианты использования и определял нужно ли подставлять typename или не нужно. Впрочем, без детального анализа сферы применения этого твоего решения, сложно что-то посоветовать конкретное.

Добавлено через 20 секунд
Цитата Сообщение от Mirmik Посмотреть сообщение
Что такое VS?
Visual Studio
0
techpriest
 Аватар для Mirmik
634 / 213 / 57
Регистрация: 27.02.2014
Сообщений: 1,180
09.01.2016, 18:49  [ТС]
Тут есть два вопроса.
Первый состоит в том, для чего макрос используется, а второй в том, какие средства мы можем применить для его реализации.

1. Макрос используется в целях, в которых он используется в языке С. То есть не для класов, не для шаблонов его применять не нужно, потому что в тех хеадерах, в которых он значиться ничего подобного появиться не может.

2. Для имитации можно использовать любые, доступные компилятору средства, до тех пор, пока мы в состоянии объяснить компилятору, в каком случае какой вариант стоит использовать.

Основная сложность в том, что нельзя сделать такой единый макрос, который анализировал бы варианты использования и определял нужно ли подставлять typename или не нужно.
А в каких случаях слово typename будет мешать, если, допустим, ограничиться g++ и c++11.

Добавлено через 6 минут
... Вообще, да... Что-то меня в самом начале подвинуло...

Действительно, шаблоны же изя... Так нужен ли вообще typename?
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
09.01.2016, 19:58
Цитата Сообщение от Mirmik Посмотреть сообщение
Действительно, шаблоны же изя... Так нужен ли вообще typename?
В этом случае не нужен, следовательно проблемы в этом узком варианте применения нет.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
09.01.2016, 19:58
Помогаю со студенческими работами здесь

Typeof Generic Class
Всем привет. Играюсь с архетиктурой. Есть контроллеры (сингелтоны, то есть Активатор Create Instance не работает (хотя глубоко не...

Typeof: string parameter
Всё очень просто. Каким образом корректно вызвать такой код: string className = &quot;myClass&quot;; Type type = typeof(className );...

Имя встроенного типа из typeof
Добрый день, вопрос банально прост если мы имеем: System.Type type = typeof(int); то как из type =&gt; получить значение...

Type.GetType вместо typeof()
Приветствую. Получаю System.Type через typeof(NameClass). Но необходимо получать тип по значению из строковой переменной, т.е....

Возможен ли метод с типом Task<typeof(y)>
Не подскажите, как написать что нибуть такое: public Task&lt;typeof(y)&gt; X (Type y) { return 1 as y; } Что бы можно было...


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

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Новые блоги и статьи
изучаю kubernetes
lagorue 13.01.2026
А пригодятся-ли мне знания kubernetes в России?
сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru