Możliwe jest napisanie funkcji, która po skompilowaniu kompilatorem C zwróci 0, a skompilowana kompilatorem C ++ zwróci 1 (trywialne rozwiązanie
#ifdef __cplusplus
nie jest interesujące).
Na przykład:
int isCPP()
{
return sizeof(char) == sizeof 'c';
}
Oczywiście powyższe zadziała tylko wtedy, gdy sizeof (char)
nie jest takie samo jaksizeof (int)
Innym, bardziej przenośnym rozwiązaniem jest coś takiego:
int isCPP()
{
typedef int T;
{
struct T
{
int a[2];
};
return sizeof(T) == sizeof(struct T);
}
}
Nie jestem pewien, czy przykłady są w 100% poprawne, ale masz pomysł. Uważam, że są też inne sposoby na napisanie tej samej funkcji.
Jakie różnice, jeśli w ogóle, między C ++ 03 i C ++ 11 można wykryć w czasie wykonywania? Innymi słowy, czy można napisać podobną funkcję, która zwróciłaby wartość logiczną wskazującą, czy jest kompilowana przez zgodny kompilator C ++ 03 czy kompilator C ++ 11?
bool isCpp11()
{
//???
}
c++
c++11
c++03
language-detection
Armen Tsirunyan
źródło
źródło
Odpowiedzi:
Język podstawowy
Dostęp do modułu wyliczającego przy użyciu
::
:Możesz także nadużywać nowych słów kluczowych
Ponadto fakt, że literały ciągów nie są już konwertowane na
char*
Nie wiem jednak, jak prawdopodobne jest, że będzie to działać na prawdziwej implementacji. Taki, który wykorzystuje
auto
Poniższe jest oparte na fakcie, że
operator int&&
jest to funkcja konwersji naint&&
w C ++ 0x i konwersja na,int
po której następuje logiczna - i w C ++ 03Ten przypadek testowy nie działa dla C ++ 0x w GCC (wygląda na błąd) i nie działa w trybie C ++ 03 dla clang. Zgłoszono clang PR .
Zmodyfikowane leczenie wstrzyknięto nazw klas szablonów w C ++ 11:
Do zademonstrowania istotnych zmian można użyć kilku opcji „wykryj, czy jest to C ++ 03 czy C ++ 0x”. Poniżej znajduje się zmodyfikowany przypadek testowy, który początkowo był używany do zademonstrowania takiej zmiany, ale teraz jest używany do testowania pod kątem C ++ 0x lub C ++ 03.
Biblioteka standardowa
Wykrywanie braku
operator void*
w C ++ 0x 'std::basic_ios
źródło
true
dla MSVC 2005 i nowszych, a błąd kompilacji w MSVC 2003.(...)
vs.(char*)
Naprawdę to lubię!Inspirację zaczerpnąłem z Jakie przełomowe zmiany zostały wprowadzone w C ++ 11? :
Jest to oparte na nowych literałach ciągów, które mają pierwszeństwo przed interpretacją makr.
źródło
#undef u8
to użycie preprocesora jest widoczne tylko wtedy, gdy twój program ma wcześniej zdefiniowane makro o nazwieu8
(boooo). Jeśli jest to prawdziwy problem, nadal można go obejść za pomocą specyficznych dla implementacji pragm / wywołań makr push / pop (wydaje mi się, że większość implementacji je ma).Co powiesz na sprawdzenie przy użyciu nowych zasad
>>
zamykania szablonów:Alternatywnie szybkie sprawdzenie
std::move
:źródło
std::move
?W przeciwieństwie do wcześniejszego C ++, C ++ 0x umożliwia tworzenie typów referencyjnych z typów referencyjnych, jeśli ten podstawowy typ odwołania zostanie wprowadzony za pomocą, na przykład, parametru szablonu:
Perfekcyjne przekazywanie ma niestety cenę zerwania wstecznej kompatybilności.
Inny test może opierać się na obecnie dozwolonych typach lokalnych jako argumentach szablonu:
źródło
isC++0x
to prawidłowy identyfikator C ++;)To nie jest do końca poprawny przykład, ale jest to interesujący przykład, który pozwala odróżnić C od C ++ 0x (jest to jednak nieprawidłowy C ++ 03):
źródło
sizeof(int) != 1
prawdy. W systemie 0x z wyjątkowo dużymichar
s wyniki mogą być takie same. Wciąż jednak niezła sztuczka.char
jest jednak zawsze jednobajtowysizeof(char)
z definicji zawsze będzie miał wartość 1. AleCHAR_BIT
(zdefiniowane w limits.h) może być więcej niż 8. W rezultacie obachar
iint
mogą mieć 32 bity, w którym to przypadkusizeof(int) == 1
(iCHAR_BIT == 32
).Z tego pytania :
źródło
bool is_cpp0x = !test[0].flag;
T
podczas gdy konstrukcje kopiujące C ++ 03 zT()
Chociaż nie jest to takie zwięzłe ... W obecnym C ++ nazwa szablonu klasy jest interpretowana jako nazwa typu (nie nazwa szablonu) w zakresie tego szablonu klasy. Z drugiej strony nazwa szablonu klasy może być używana jako nazwa szablonu w C ++ 0x (N3290 14.6.1 / 1).
źródło
źródło