Можно написать функцию, которая при компиляции с помощью компилятора C вернет 0, а при компиляции с помощью компилятора C ++ - 1 (тривиальное решение с помощью
#ifdef __cplusplus
не интересно).
Например:
int isCPP()
{
return sizeof(char) == sizeof 'c';
}
Конечно, это будет работать, только если sizeof (char)
не то же самое, что иsizeof (int)
Другое, более портативное решение выглядит примерно так:
int isCPP()
{
typedef int T;
{
struct T
{
int a[2];
};
return sizeof(T) == sizeof(struct T);
}
}
Я не уверен, что примеры на 100% верны, но идею вы поняли. Я считаю, что есть и другие способы написать ту же функцию.
Какие различия, если таковые имеются, между C ++ 03 и C ++ 11 можно обнаружить во время выполнения? Другими словами, можно ли написать аналогичную функцию, которая возвращала бы логическое значение, указывающее, компилируется ли она соответствующим компилятором C ++ 03 или компилятором C ++ 11?
bool isCpp11()
{
//???
}
источник
Ответы:
Основной язык
Доступ к перечислителю с помощью
::
:Вы также можете злоупотреблять новыми ключевыми словами
Кроме того, тот факт, что строковые литералы больше не преобразуются в
char*
Я не знаю, насколько вероятно, что это будет работать над реальной реализацией. Тот, который эксплуатирует
auto
Следующее основано на том факте, что
operator int&&
это функция преобразованияint&&
в C ++ 0x и преобразование в,int
за которым следует логический - и в C ++ 03Этот тестовый пример не работает для C ++ 0x в GCC (выглядит как ошибка) и не работает в режиме C ++ 03 для clang. Был подан лязг PR .
Модифицирована обработка вводимых имен классов шаблонов в C ++ 11:
Для демонстрации критических изменений можно использовать пару «определить, C ++ это ли это или C ++ 0x». Ниже приведен измененный тестовый пример, который изначально использовался для демонстрации такого изменения, но теперь используется для тестирования на C ++ 0x или C ++ 03.
Стандартная библиотека
Обнаружение отсутствия
operator void*
в C ++ 0x 'std::basic_ios
источник
true
для MSVC 2005 и далее, а также ошибка компиляции в MSVC 2003.(...)
против(char*)
вызовов. Мне это очень нравится!Я получил вдохновение из того, какие критические изменения внесены в C ++ 11? :
Это основано на новых строковых литералах, которые имеют приоритет над расширением макроса.
источник
#undef u8
то использование препроцессора можно наблюдать только в том случае, если ваша программа имеет предварительно определенный макрос с именемu8
(boooo). Если это реальная проблема, это все еще можно обойти, используя специфические для реализации прагмы / вызовы макросов push / pop (я считаю, что в большинстве реализаций они есть).Как насчет проверки по новым правилам
>>
закрытия шаблонов:В качестве альтернативы быстрая проверка
std::move
:источник
std::move
?В отличие от предыдущего C ++, C ++ 0x позволяет создавать ссылочные типы из ссылочных типов, если этот базовый ссылочный тип вводится, например, с помощью параметра шаблона:
К сожалению, безупречная переадресация достигается ценой нарушения обратной совместимости.
Другой тест может быть основан на теперь разрешенных локальных типах в качестве аргументов шаблона:
источник
isC++0x
действительный ли это идентификатор C ++;)Это не совсем правильный пример, но это интересный пример, который позволяет отличить C от C ++ 0x (хотя он недействителен C ++ 03):
источник
sizeof(int) != 1
правду. В системе 0x с исключительно большимchar
s результаты могут быть такими же. Тем не менее, это все еще изящный трюк.char
всегда один байтsizeof(char)
всегда будет 1 по определению. НоCHAR_BIT
(определено в limits.h) может быть больше 8. В результате обаchar
иint
могут иметь 32 бита, и в этом случаеsizeof(int) == 1
(иCHAR_BIT == 32
).Из этого вопроса :
источник
bool is_cpp0x = !test[0].flag;
T
тогда как конструкции C ++ 03 копируют изT()
Хотя и не так кратко ... В текущем C ++ имя шаблона класса само по себе интерпретируется как имя типа (а не имя шаблона) в области действия этого шаблона класса. С другой стороны, имя шаблона класса может использоваться как имя шаблона в C ++ 0x (N3290 14.6.1 / 1).
источник
источник