Es ist möglich, eine Funktion zu schreiben, die beim Kompilieren mit einem C-Compiler 0 und beim Kompilieren mit einem C ++ - Compiler 1 zurückgibt (die triviale Lösung mit
#ifdef __cplusplus
ist nicht interessant).
Beispielsweise:
int isCPP()
{
return sizeof(char) == sizeof 'c';
}
Natürlich funktioniert das oben Genannte nur, wenn sizeof (char)
es nicht dasselbe ist wiesizeof (int)
Eine andere, tragbarere Lösung ist ungefähr so:
int isCPP()
{
typedef int T;
{
struct T
{
int a[2];
};
return sizeof(T) == sizeof(struct T);
}
}
Ich bin nicht sicher, ob die Beispiele 100% korrekt sind, aber Sie bekommen die Idee. Ich glaube, es gibt auch andere Möglichkeiten, dieselbe Funktion zu schreiben.
Welche Unterschiede zwischen C ++ 03 und C ++ 11 können gegebenenfalls zur Laufzeit festgestellt werden? Mit anderen Worten, ist es möglich, eine ähnliche Funktion zu schreiben, die einen booleschen Wert zurückgibt, der angibt, ob sie von einem konformen C ++ 03-Compiler oder einem C ++ 11-Compiler kompiliert wird?
bool isCpp11()
{
//???
}
quelle
Antworten:
Kernsprache
Zugriff auf einen Enumerator mit
::
:Sie können die neuen Schlüsselwörter auch missbrauchen
Auch die Tatsache, dass String-Literale nicht mehr konvertiert werden
char*
Ich weiß jedoch nicht, wie wahrscheinlich es ist, dass Sie an einer echten Implementierung arbeiten. Eine, die ausnutzt
auto
Das Folgende basiert auf der Tatsache, dass
operator int&&
es sich um eine Konvertierungsfunktionint&&
in C ++ 0x und eine Konvertierung inint
gefolgt von logisch und in C ++ 03 handeltDieser Testfall funktioniert nicht für C ++ 0x in GCC (sieht aus wie ein Fehler) und funktioniert nicht im C ++ 03-Modus für Clang. Eine klirrende PR wurde eingereicht .
Die modifizierte Behandlung injizierter Klassennamen von Vorlagen in C ++ 11:
Ein paar "Erkennen, ob dies C ++ 03 oder C ++ 0x ist" können verwendet werden, um wichtige Änderungen zu demonstrieren. Das Folgende ist ein optimierter Testfall, der ursprünglich verwendet wurde, um eine solche Änderung zu demonstrieren, jetzt aber zum Testen auf C ++ 0x oder C ++ 03 verwendet wird.
Standardbibliothek
Erkennen des Mangels an
operator void*
in C ++ 0x 'std::basic_ios
quelle
true
für MSVC 2005 und einen Kompilierungsfehler in MSVC 2003 zurück.(...)
vs-(char*)
Anrufe. Das gefällt mir sehr!Ich habe mich inspirieren lassen von Welche bahnbrechenden Änderungen werden in C ++ 11 eingeführt? ::
Dies basiert auf den neuen Zeichenfolgenliteralen, die Vorrang vor der Makroerweiterung haben.
quelle
#undef u8
die Präprozessorverwendung nur beobachtet werden, wenn Ihr Programm über ein zuvor definiertes Makro mit dem Namenu8
(boooo) verfügt. Wenn dies ein echtes Problem ist, kann dies immer noch mit implementierungsspezifischen Push / Pop-Makro-Pragmas / -Aufrufen umgangen werden (die meisten Implementierungen haben diese, glaube ich).Wie wäre es mit einer Prüfung unter Verwendung der neuen Regeln zum
>>
Schließen von Vorlagen:Alternativ eine schnelle Überprüfung auf
std::move
:quelle
std::move
?Im Gegensatz zu früheren Versionen von C ++ können mit C ++ 0x Referenztypen aus Referenztypen erstellt werden, wenn dieser Basisreferenztyp beispielsweise über einen Vorlagenparameter eingeführt wird:
Eine perfekte Weiterleitung kostet leider die Abwärtskompatibilität.
Ein weiterer Test könnte auf jetzt zulässigen lokalen Typen als Vorlagenargumente basieren:
quelle
isC++0x
es sich um eine gültige C ++ - Kennung handelt;)Dies ist kein richtiges Beispiel, aber es ist ein interessantes Beispiel, das C von C ++ 0x unterscheiden kann (es ist jedoch ungültiges C ++ 03):
quelle
sizeof(int) != 1
dass es wahr ist. Auf einem 0x-System mit außergewöhnlich großenchar
s können die Ergebnisse gleich sein. Trotzdem ein ordentlicher Trick.char
ist immer ein Bytesizeof(char)
ist per Definition immer 1. AberCHAR_BIT
(definiert in limits.h) darf mehr als 8 sein. Infolgedessen können beidechar
undint
32 Bits haben, in welchem Fallsizeof(int) == 1
(undCHAR_BIT == 32
).Aus dieser Frage :
quelle
bool is_cpp0x = !test[0].flag;
T
während C ++ 03 Kopierkonstrukte vonT()
Obwohl nicht so prägnant ... In aktuellem C ++ wird der Name der Klassenvorlage selbst als Typname (kein Vorlagenname) im Bereich dieser Klassenvorlage interpretiert. Andererseits kann der Name der Klassenvorlage in C ++ 0x (N3290 14.6.1 / 1) als Vorlagenname verwendet werden.
quelle
quelle