Wie kann ich den Wert von a enum class
in C ++ 11 ausgeben ? In C ++ 03 ist es so:
#include <iostream>
using namespace std;
enum A {
a = 1,
b = 69,
c= 666
};
int main () {
A a = A::c;
cout << a << endl;
}
In c ++ 0x wird dieser Code nicht kompiliert
#include <iostream>
using namespace std;
enum class A {
a = 1,
b = 69,
c= 666
};
int main () {
A a = A::c;
cout << a << endl;
}
prog.cpp:13:11: error: cannot bind 'std::ostream' lvalue to 'std::basic_ostream<char>&&'
/usr/lib/gcc/i686-pc-linux-gnu/4.5.1/../../../../include/c++/4.5.1/ostream:579:5: error: initializing argument 1 of 'std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char, _Traits = std::char_traits<char>, _Tp = A]'
zusammengestellt bei Ideone.com
Antworten:
Im Gegensatz zu einer Aufzählung ohne Gültigkeitsbereich kann eine Aufzählung mit Gültigkeitsbereich nicht implizit in ihren ganzzahligen Wert konvertiert werden. Sie müssen es mithilfe einer Umwandlung explizit in eine Ganzzahl konvertieren:
Möglicherweise möchten Sie die Logik in eine Funktionsvorlage einkapseln:
benutzt als:
quelle
as_integer
aus einer meiner Open-Source-Bibliotheken, CxxReflect, kopiert (siehe enumeration.hpp ). Die Bibliothek verwendet überall konsistent nachfolgende Rückgabetypen. Aus Gründen der Konsistenz.as_integer
kann so definiert werdenconstexpr
, dass es in Kontexten verwendet werden kann, in denen ein konstanter Ausdruck erforderlich ist.quelle
g++ -std=c++0x enum.cpp
aber es werden einige Compilerfehler angezeigt -> pastebin.com/JAtLXan9 . Ich konnte das Beispiel von @ james-mcnellis auch nicht kompilieren.Es ist möglich, dass Ihr zweites Beispiel (dh das mit einer Aufzählung mit Gültigkeitsbereich) mit derselben Syntax wie Aufzählungen ohne Gültigkeitsbereich funktioniert. Darüber hinaus ist die Lösung generisch und funktioniert für alle Enums mit Gültigkeitsbereich, während Code für jede Enumeration mit Gültigkeitsbereich geschrieben wird (wie in der Antwort von @ForEveR gezeigt) ).
Die Lösung besteht darin, eine generische
operator<<
Funktion zu schreiben, die für jede Enumeration mit Gültigkeitsbereich funktioniert. Die Lösung verwendet SFINAE überstd::enable_if
und ist wie folgt.quelle
typename
vorherstd::underlying_type<T>::type
.error: cannot bind ‘std::basic_ostream<char>’ lvalue to ‘std::basic_ostream<char>&&’
. Dies scheint daran zu liegen, dass bei einem temporären Stream die ADL fehlschlägt und die obige Vorlage nicht möglich ist. Irgendwelche Tipps?cout
Anweisungen in eine einzigecout
Anweisung konvertiert, indem ich die<<
Operatoren miteinander verkettet habe . Siehe hier(Ich darf noch keinen Kommentar abgeben.) Ich würde die folgenden Verbesserungen der bereits großartigen Antwort von James McNellis vorschlagen:
mit
constexpr
: Erlaubt mir, einen Enum-Member-Wert als Array-Größe zur Kompilierungszeit zu verwendenstatic_assert
+is_enum
: um die Kompilierungszeit sicherzustellen, dass die Funktion etw. nur mit Aufzählungen, wie vorgeschlagenÜbrigens frage ich mich: Warum sollte ich jemals verwenden,
enum class
wenn ich meinen Enum-Mitgliedern Zahlenwerte zuweisen möchte?! Berücksichtigung des Konvertierungsaufwands.Vielleicht würde ich dann wieder zum Normalen zurückkehren
enum
Normalen wie ich hier vorgeschlagen habe: Wie verwende ich Enums als Flags in C ++?Noch eine (bessere) Variante davon ohne static_assert, basierend auf einem Vorschlag von @TobySpeight:
quelle
T
für den esstd::underlying_type<T>::type
gibt, der aberstd::is_enum<T>::value
falsch ist? Wenn nicht, dannstatic_assert
fügt das keinen Wert hinzu.Enumeration
es sich nicht um einen vollständigen Aufzählungstyp handelt. In diesem Fall ist es möglicherweise bereits zu spät, da es im Rückgabetyp verwendet wird. Vielleicht könnten wirstd::enable_if<std::is_enum<Enumeration>::value, std::underlying_type<Enumeration>::type>
als Rückgabetyp angeben ? Natürlich ist es so viel einfacher (und die Fehlermeldungen so viel klarer), wenn Sie einen Compiler mit Unterstützung für Konzepte haben ...Einfacher schreiben,
quelle
Folgendes hat in C ++ 11 für mich funktioniert:
quelle
Sie könnten so etwas tun:
quelle