Frage

Ich versuche etwa Folgendes zu tun:

enum E;

void Foo(E e);

enum E {A, B, C};

was der Compiler ablehnt.Ich habe einen kurzen Blick auf Google geworfen und der Konsens scheint zu sein: „Das geht nicht“, aber ich verstehe nicht, warum.Kann mir das jemand erklären?

Klarstellung 2:Ich mache das, weil ich private Methoden in einer Klasse habe, die diese Aufzählung annehmen, und ich nicht möchte, dass die Werte der Aufzählung offengelegt werden – also möchte ich zum Beispiel nicht, dass jemand weiß, dass E definiert ist als

enum E {
    FUNCTIONALITY_NORMAL, FUNCTIONALITY_RESTRICTED, FUNCTIONALITY_FOR_PROJECT_X
}

Ich möchte nicht, dass meine Benutzer etwas über Projekt X erfahren.

Deshalb wollte ich die Aufzählung weiterleiten, damit ich die privaten Methoden in die Header-Datei einfügen, die Aufzählung intern im CPP deklarieren und die erstellte Bibliotheksdatei und den Header an die Leute verteilen kann.

Was den Compiler betrifft – es ist GCC.

War es hilfreich?

Lösung

Der Grund für die ENUM kann nicht nach vorne ist zu erklären, dass die Werte, ohne zu wissen, kann der Compiler weiß die Speicherung nicht für das ENUM-Variable erforderlich. C ++ Compilers dürfen den tatsächlichen Speicherplatz angeben, basierend auf der Größe notwendig angegeben, alle Werte zu enthalten. Wenn alles, was sichtbar ist, die Vorwärts-Deklaration ist, kann die Übersetzungseinheit nicht wissen, welche Speichergröße gewählt worden sein -. Es ist ein Zeichen oder ein int sein könnte, oder etwas anderes


Aus Abschnitt 7.2.5 der ISO C ++ Standard:

  

Die zugrunde liegenden Typ einer Aufzählung ist ein integraler Typ, der alle Aufzählungswerte definiert in der Aufzählung darstellen kann. Es ist die Implementierung definiert, die integraler Typ wie der zugrunde liegende Typ für eine Aufzählung verwendet wird, außer dass der zugrunde liegende Typ darf nicht größer sein als int es sei denn, der Wert eines Aufzählungs nicht in einem int oder unsigned int passen. Wenn die enumerator-Liste leer ist, ist der zugrunde liegende Typ, als ob die Aufzählung einen einzigen enumerator mit dem Wert 0. Der Wert von sizeof() auf einen Aufzählungstyp angewandt hatte, um ein Objekt von Aufzählungstyp oder einen Enumerator ist der Wert von sizeof() auf den zugrunde liegenden Typ angewendet wird.

Da die Anrufer , um die Funktion müssen die Größen der Parameter richtig eingestellt den Call-Stack kennen, die Anzahl der Zählungen in einer Aufzählung Liste muss vor dem Funktionsprototyp bekannt sein.

Update: In C ++ 0X eine Syntax für foreward erklärt Aufzählungstypen vorgeschlagen und angenommen wurde. Sie können den Vorschlag sehen unter http: // www .open-std.org / JTC1 / SC22 / WG21 / docs / paper / 2008 / n2764.pdf

Andere Tipps

Weiterleiten Erklärung Aufzählungen ist auch möglich, in C ++ 0x. Bisher konnte der Grund Enum-Typen nicht nach vorne ist deklariert werden, da die Größe der Aufzählung auf dessen Inhalt abhängt. Solange die Größe der Aufzählung durch die Anwendung angegeben ist, kann es nach vorne deklariert werden:

enum Enum1;                   //Illegal in C++ and C++0x; no size is explicitly specified.
enum Enum2 : unsigned int;    //Legal in C++0x.
enum class Enum3;             //Legal in C++0x, because enum class declarations have a default type of "int".
enum class Enum4: unsigned int; //Legal C++0x.
enum Enum2 : unsigned short;  //Illegal in C++0x, because Enum2 was previously declared with a different type.

Ich füge eine up-to-date Antwort hier, angesichts der jüngsten Entwicklungen.

Sie können eine ENUM in C ++ 11, zukunfts erklären, solange Sie ihren Speichertyp zur gleichen Zeit erklären. Die Syntax sieht wie folgt aus:

enum E : short;
void foo(E e);

....

enum E : short
{
    VALUE_1,
    VALUE_2,
    ....
}

In der Tat, wenn die Funktion nicht auf die Werte der Aufzählung bezieht, brauchen Sie nicht die vollständige Erklärung überhaupt an diesem Punkt.

Dies wird durch G unterstützt ++ 4.6 und ab (-std=c++0x oder -std=c++11 in neueren Versionen). Visual C ++ 2013 unterstützt dies; in früheren Versionen hat es eine Art von Nicht-Standard-Unterstützung, die ich aus noch nicht herausgefunden haben -. Ich fand einen Vorschlag machen, dass eine einfache Vorwärtsdeklaration ist legal, aber YMMV

Weiterleiten Dinge in C ++ zu erklären ist sehr nützlich, weil es href="http://brianbondy.com/blog/id/5/slow-compilation-time" rel="noreferrer"> . Sie können mehrere Dinge in C ++ weiterleiten erklären einschließlich: struct, class, function, etc ...

Aber kann man vorwärts ein enum in C ++ deklarieren?

Nein kann man nicht.

Aber warum es nicht zulassen? Wenn es erlaubt wurde, können Sie Ihren enum Typen in Ihrer Header-Datei und Ihre enum Werte in der Quelldatei definieren. Klingt wie sollte es richtig erlaubt sein?

Falsch.

In C ++ gibt es keinen Standardtyp für enum wie es in C # (int) ist. In C ++ wird Ihr enum Typ vom Compiler bestimmt werden, um jede Art zu sein, die den Wertebereich passen Sie für Ihre enum haben.

Was bedeutet das?

Es bedeutet, dass Ihre enum zugrunde liegenden Typ nicht vollständig bestimmt werden kann, bis Sie alle Werte des enum definiert haben. Welche bemannt Sie nicht die Deklaration und Definition Ihrer enum trennen kann. Und deshalb kann man nicht nach vorne einem enum in C ++ deklariert.

Die ++ ISO-C-Standard S7.2.5:

  

Der zugrunde liegende Typ einer Enumeration ist ein integraler Typ, der alle Aufzählungswerte definiert in der Aufzählung darstellen kann. Es ist die Implementierung definiert, die integraler Typ wie der zugrunde liegende Typ für eine Aufzählung verwendet wird, außer dass der zugrunde liegende Typ darf nicht größer sein als int es sei denn, der Wert eines Aufzählungs nicht in einem int oder unsigned int passen. Wenn die Enumerator-Liste leer ist, ist der zugrunde liegende Typ als ob die Zählung einen einzelnen Enumerator mit dem Wert 0. Der Wert von sizeof() auf einen Aufzählungstyp angewandt worden, ein Objekt des Aufzählungstypen oder einen Enumerator, ist der Wert von sizeof() angewandt auf den zugrunde liegenden Typ.

Sie können die Größe eines Aufzählungstyp in C ++ bestimmen, indem Sie den sizeof Operator. Die Größe des Aufzählungstypen ist die Größe des zugrunde liegenden Typs. Auf diese Weise können Sie erraten, welche Art des Compiler für Ihren enum verwendet.

Was passiert, wenn Sie die Art Ihrer enum explizit wie folgt an:

enum Color : char { Red=0, Green=1, Blue=2};
assert(sizeof Color == 1);

Können Sie dann erklären uns auf Ihre enum?

Nein. Aber warum nicht?

den Typ eines enum Angabe ist eigentlich nicht Teil des aktuellen C ++ Standard. Es ist eine VC ++ Erweiterung. Es wird zwar ein Teil von C ++ 0x sein.

Quelle

[Meine Antwort ist falsch, aber ich habe es hier gelassen, weil die Kommentare nützlich sind].

Weiterleiten Aufzählungen erklärt ist Nicht-Standard, weil Zeiger auf verschiedene Aufzählungstypen sind nicht auf die gleiche Größe garantiert. Der Compiler muß, um die Definition zu sehen zu wissen, welche Größe Zeiger kann mit dieser Art verwendet werden.

In der Praxis zumindest auf allen gängigen Compiler, Zeiger auf Aufzählungen sind eine einheitliche Größe. Forward-Deklaration von Aufzählungen wird als Spracherweiterung von Visual C ++ zur Verfügung gestellt, zum Beispiel.

Es ist in der Tat nicht so etwas wie eine Vorwärtsdeklaration von ENUM. Als Definition des Enum keinen Code enthalten, die auf anderem Code mit der Enum verlassen konnten, ist es in der Regel kein Problem, die Enum vollständig zu definieren, wenn Sie es zuerst sind zu deklarieren.

Wenn die einzige Nutzung Ihrer ENUM durch private Member-Funktionen, können Sie Verkapselung implementieren, indem die Enumeration mit sich selbst als Privat Mitglied dieser Klasse. Der enum hat noch voll an dem Punkt der Erklärung festgelegt werden, das heißt, innerhalb der Klassendefinition. Dies ist jedoch kein größeres Problem, da es private Member-Funktionen erklärt, und ist kein schlechter exposal der Umsetzung Interna als das.

Wenn Sie einen tieferen Grad der Verschleierung für Ihre Implementierungsdetails benötigen, können Sie es in eine abstrakte Schnittstelle brechen, nur aus reinen virtuellen Funktionen aus, und ein Beton, vollständig verdeckt, Klasse Umsetzung (vererben), um die Schnittstelle. Erstellung von Klasseninstanzen kann durch eine Fabrik oder eine statische Memberfunktion der Schnittstelle behandelt werden. Auf diese Weise, auch die realen Klassennamen, geschweige denn seine privaten Funktionen, nicht ausgesetzt werden.

Nur unter Hinweis darauf, dass der Grund, eigentlich , dass die Größe der Enumeration ist noch nicht nach vorne Erklärung bekannt. Nun, verwenden Sie Forward-Deklaration einer Struktur der Lage sein, einen Zeiger passieren um oder verweisen auf ein Objekt von einem Ort, der zu refered ist in der Vorwärts struct Definition erklärt sich auch.

Weiterleiten erklärt eine Enumeration nicht zu nützlich wäre, weil man durch Wert um die ENUM passieren zu können, wünschen würde. Sie konnten nicht einmal einen Zeiger auf sie haben, weil ich vor kurzem einige Plattformen Zeiger unterschiedlicher Größe für char gesagt wurde, als für int oder lang. So ist es hängt alles von dem Inhalt der Enumeration.

Die aktuelle C ++ Standard-verweigert das tun ausdrücklich etwas wie

enum X;

(in 7.1.5.3/1). Aber die nächste C ++ Standard-Grund im nächsten Jahr ermöglicht die folgende, die mir das Problem überzeugt eigentlich hat mit der zugrunde liegenden Art zu tun:

enum X : int;

Es ist als „undurchsichtig“ Enum Erklärung bekannt. Sie können auch X von Wert verwenden in dem folgenden Code. Und seine Enumeratoren können später in einem späteren Neudeklaration der Aufzählung definiert werden. Siehe 7.2 im aktuellen Arbeitsentwurf.

ich tun würde es so aus:

[im öffentlichen Header]

typedef unsigned long E;

void Foo(E e);

[im internen Header]

enum Econtent { FUNCTIONALITY_NORMAL, FUNCTIONALITY_RESTRICTED, FUNCTIONALITY_FOR_PROJECT_X,
  FORCE_32BIT = 0xFFFFFFFF };

Durch das Hinzufügen FORCE_32BIT wir sicherstellen, dass eContent auf eine lange kompiliert, so ist es austauschbar mit E.

Scheint es nicht voraus erklärt in GCC werden!

Interessante Diskussion hier

Wenn Sie wirklich Ihre Enum nicht wollen in Ihrer Header-Datei angezeigt werden und sicherstellen, dass es nur durch private Methoden verwendet wird, dann eine Lösung mit dem Pimpl Prinzip zu gehen.

Es ist eine Technik, die die Klasse Einbauten in den Headern von nur erklärt verstecken gewährleisten:

class A 
{
public:
    ...
private:
    void* pImpl;
};

Dann in der Implementierung-Datei (CPP), eine Klasse deklarieren, die die Darstellung der Einbauten sein werden.

class AImpl
{
public:
    AImpl(A* pThis): m_pThis(pThis) {}

    ... all private methods here ...
private:
    A* m_pThis;
};

Sie müssen dynamisch die Implementierung in der Klasse Konstruktor erstellen und im Destruktor löschen und wenn öffentliche Methode implementieren, müssen Sie verwenden:

((AImpl*)pImpl)->PrivateMethod();

Es gibt Profis für Pimpl verwenden, ist, dass es Ihre Klasse-Header von der Implementierung entkoppeln, ohne dass andere Klassen neu zu kompilieren, wenn eine Klasse Implementierung ändern. Ein weiterer Grund ist, dass sich beschleunigt Ihre Kompilierung, weil Ihre Header so einfach sind.

Aber es ist ein Schmerz zu verwenden, so sollte man sich wirklich fragen, ob nur als privat Ihre Enum erklärt in der Kopfzeile ist, dass viel Mühe.

Sie können die Enum in einer Struktur wickeln, in einigen Konstrukteuren und Typkonvertierungen hinzufügen und sie darauf, die Struktur stattdessen erklären.

#define ENUM_CLASS(NAME, TYPE, VALUES...) \
struct NAME { \
    enum e { VALUES }; \
    explicit NAME(TYPE v) : val(v) {} \
    NAME(e v) : val(v) {} \
    operator e() const { return e(val); } \
    private:\
        TYPE val; \
}

Dies scheint zu funktionieren: http://ideone.com/TYtP2

Es gibt einige Meinungsverschiedenheiten, seit dies (irgendwie) verworfen wurde, daher hier einige relevante Teile des Standards.Untersuchungen zeigen, dass der Standard die Vorwärtsdeklaration nicht wirklich definiert und auch nicht ausdrücklich angibt, dass Aufzählungen vorwärts deklariert werden können oder nicht.

Erstens aus dcl.enum, Abschnitt 7.2:

Die zugrunde liegende Art einer Aufzählung ist ein integraler Typ, der alle in der Aufzählung definierten Enumeratorwerte darstellen kann.Es ist implementiert definiert, welcher Integraltyp als zugrunde liegender Typ für eine Aufzählung verwendet wird, außer dass der zugrunde liegende Typ nicht größer als int ist, es sei denn, der Wert eines Enumerators kann nicht in einen int oder nicht signierten int passen.Wenn die Enumerator-Liste leer ist, ist der zugrunde liegende Typ so, als ob die Aufzählung einen einzelnen Aufzähler mit Wert 0 hätte.Der Wert von sizeof (), der auf einen Aufzählungstyp, ein Objekt des Aufzählungstyps oder eines Aufzählers angewendet wird, ist der Wert von sizeof (), der auf den zugrunde liegenden Typ angewendet wird.

Der zugrunde liegende Typ einer Aufzählung ist also mit einer geringfügigen Einschränkung durch die Implementierung definiert.

Als Nächstes wenden wir uns dem Abschnitt über „unvollständige Typen“ (3.9) zu, der in etwa so nah wie kein anderer Standard für Vorwärtsdeklarationen ist:

Eine Klasse, die deklariert, aber nicht definiert wurde, oder eine Reihe unbekannter Größe oder unvollständiger Elementtyp, ist ein unvollständig definierter Objekttyp.

Ein Klassentyp (z. B. "Klasse X") kann an einem Punkt in einer Übersetzungseinheit unvollständig sein und später abgeschlossen sein.Der Typ „Klasse X“ ist an beiden Punkten vom gleichen Typ.Der deklarierte Typ eines Array -Objekts könnte ein Array von unvollständigem Klassentyp sein und daher unvollständig;Wenn der Klassentyp später in der Übersetzungseinheit abgeschlossen ist, wird der Array -Typ abgeschlossen.Der Array-Typ an diesen beiden Punkten ist vom gleichen Typ.Der deklarierte Typ eines Array -Objekts könnte ein Array unbekannter Größe sein und daher an einem Punkt in einer Übersetzungseinheit unvollständig und später abgeschlossen sein.Die Array -Typen an diesen beiden Punkten ("Array der unbekannten Grenzen von T" und "Array von NT") sind unterschiedliche Typen.Der Typ eines Zeigers auf eine Reihe unbekannter Größe oder eines Typs, der durch eine Typedef -Deklaration als eine Reihe unbekannter Größe definiert wird, kann nicht abgeschlossen werden.

Der Standard legt also im Großen und Ganzen die Typen fest, die vorwärts deklariert werden können.Enum war nicht vorhanden, daher betrachten Compiler-Autoren die Vorwärtsdeklaration aufgrund der variablen Größe des zugrunde liegenden Typs im Allgemeinen als vom Standard nicht zulässig.

Es macht auch Sinn.Auf Aufzählungen wird normalerweise in Wertsituationen verwiesen, und der Compiler müsste in solchen Situationen tatsächlich die Speichergröße kennen.Da die Speichergröße durch die Implementierung definiert wird, entscheiden sich viele Compiler möglicherweise einfach dafür, 32-Bit-Werte für den zugrunde liegenden Typ jeder Aufzählung zu verwenden, woraufhin es möglich wird, sie weiterzudeklarieren.Ein interessantes Experiment könnte darin bestehen, zu versuchen, eine Enumeration in Visual Studio vorwärts zu deklarieren und sie dann zu zwingen, einen zugrunde liegenden Typ zu verwenden, der größer als sizeof(int) ist, wie oben erläutert, um zu sehen, was passiert.

Für VC, hier ist der Test über Forward-Deklaration und die Angabe zugrunde liegenden Typ:

  1. der folgende Code kompiliert ok.
    typedef int myint;
    enum T ;
    void foo(T * tp )
    {
        * tp = (T)0x12345678;
    }
    enum T : char
    {
        A
    };

Aber bekam die Warnung für / W4 (/ W3 nicht entstehen diese Warnung)

Warnung C4480: Nicht-Standard-Erweiterung verwendet: zugrunde liegenden Typs für Enum 'T' Angabe

  1. VC (Microsoft (R) 32-Bit-C / C ++ Optimizing Compiler Version 15.00.30729.01 für 80x86) Buggy im obigen Fall aussieht:

    • , wenn Enum T zu sehen; VC nimmt den ENUM-Typ-T-Standard-4 Bytes int als Grundtyp verwendet, so dass die erzeugte Assembler-Code lautet:
    ?foo@@YAXPAW4T@@@Z PROC                 ; foo
    ; File e:\work\c_cpp\cpp_snippet.cpp
    ; Line 13
        push    ebp
        mov ebp, esp
    ; Line 14
        mov eax, DWORD PTR _tp$[ebp]
        mov DWORD PTR [eax], 305419896      ; 12345678H
    ; Line 15
        pop ebp
        ret 0
    ?foo@@YAXPAW4T@@@Z ENDP                 ; foo

Das oben gezeigte Assembler-Code wird aus /Fatest.asm extrahiert direkt, nicht meine persönliche Vermutung. Sehen Sie das mov DWORD PTR [eax], 305419896; 12345678H Linie?

Der folgende Codeausschnitt beweist es:

    int main(int argc, char *argv)
    {
        union {
            char ca[4];
            T t;
        }a;
        a.ca[0] = a.ca[1] = a.[ca[2] = a.ca[3] = 1;
        foo( &a.t) ;
        printf("%#x, %#x, %#x, %#x\n",  a.ca[0], a.ca[1], a.ca[2], a.ca[3] );
        return 0;
    }

ist das Ergebnis: 0x78, 0x56, 0x34, 0x12

  • nach der Vorwärtserklärung Enum T entfernen und die Definition der Funktion foo nach dem ENUM-T-Definition bewegen: Das Ergebnis ist OK:

die obige Tastenanweisung wird:

mov BYTE PTR [eax], 120; 00000078H

das Endergebnis: 0x78, 0x1, 0x1, 0x1

Hinweis wird der Wert nicht überschrieben werden

Also mit der Vorwärts-Deklaration von ENUM in VC gilt als schädlich.

BTW, nicht zu überraschen, die Syntax für Erklärung des zugrunde liegenden Typs ist die gleiche wie sein in C #. In pratice fand ich es 3 Byte wert ist durch die Angabe des zugrunde liegenden Typs als Zeichen zu speichern, wenn die Rede auf das Embedded-System, das Speicher begrenzt ist.

In meinen Projekten nahm ich die Namespace-Bound Enumeration Technik mit enums zu befassen aus Vermächtnis und 3rd-Party-Komponenten. Hier ein Beispiel:

forward.h:

namespace type
{
    class legacy_type;
    typedef const legacy_type& type;
}

enum.h:

// May be defined here or pulled in via #include.
namespace legacy
{
    enum evil { x , y, z };
}


namespace type
{
    using legacy::evil;

    class legacy_type
    {
    public:
        legacy_type(evil e)
            : e_(e)
        {}

        operator evil() const
        {
            return e_;
        }

    private:
        evil e_;
    };
}

foo.h:

#include "forward.h"

class foo
{
public:
    void f(type::type t);
};

foo.cc:

#include "foo.h"

#include <iostream>
#include "enum.h"

void foo::f(type::type t)
{
    switch (t)
    {
        case legacy::x:
            std::cout << "x" << std::endl;
            break;
        case legacy::y:
            std::cout << "y" << std::endl;
            break;
        case legacy::z:
            std::cout << "z" << std::endl;
            break;
        default:
            std::cout << "default" << std::endl;
    }
}

main.cc:

#include "foo.h"
#include "enum.h"

int main()
{
    foo fu;
    fu.f(legacy::x);

    return 0;
}

Beachten Sie, dass die foo.h Header nichts über legacy::evil wissen muss. Nur die Dateien, die den Legacy-Typ legacy::evil verwenden (hier: main.cc) müssen enum.h einschließen

.

Meine Lösung für Ihr Problem wäre es, entweder:

1 - Verwendung int statt Aufzählungen: Erklären Sie Ihre Ints in einem anonymen Namespace in Ihrer CPP-Datei (nicht im Header):

namespace
{
   const int FUNCTIONALITY_NORMAL = 0 ;
   const int FUNCTIONALITY_RESTRICTED = 1 ;
   const int FUNCTIONALITY_FOR_PROJECT_X = 2 ;
}

Wie Sie Ihre Methoden sind privat, niemand verwirrt mit den Daten. Sie könnten sogar noch weiter zu testen gehen, wenn jemand Ihnen ein ungültiges Datum sendet:

namespace
{
   const int FUNCTIONALITY_begin = 0 ;
   const int FUNCTIONALITY_NORMAL = 0 ;
   const int FUNCTIONALITY_RESTRICTED = 1 ;
   const int FUNCTIONALITY_FOR_PROJECT_X = 2 ;
   const int FUNCTIONALITY_end = 3 ;

   bool isFunctionalityCorrect(int i)
   {
      return (i >= FUNCTIONALITY_begin) && (i < FUNCTIONALITY_end) ;
   }
}

2: eine volle Klasse mit begrenzt const instantiations erstellen, wie in Java getan. Weiterleiten, um die Klasse erklären, und es dann in der CPP-Datei definieren, und instanziiert nur die ENUM-ähnlichen Werte. Ich habe so etwas wie die in C ++, und das Ergebnis war nicht so befriedigend wie gewünscht, da es einige Codes benötigte eine ENUM (Kopie Konstruktion, operator = usw.) Zu simulieren.

3: Wie zuvor vorgeschlagen, verwenden Sie die privat deklarierten Aufzählungs. Trotz der Tatsache, wird ein Benutzer seine volle Definition sieht, wird es nicht in der Lage sein, es zu benutzen, noch die privaten Methoden. So werden Sie normalerweise in der Lage sein, die Enum und den Inhalt der bestehenden Methoden zu ändern, ohne neu zu kompilieren von Code zu benötigen Ihre Klasse.

Meine Vermutung wäre entweder die Lösung 3 oder 1 sein.

Da die Enum integraler Größe von unterschiedlicher Größe sein kann (der Compiler entscheidet, welche Größe eine gegebene Enum hat), der Zeiger auf die ENUM auch Größe haben kann, variiert, da sie integraler Typ ist (Zeichen haben Zeiger einer anderen Größe auf einigen Plattformen zum Beispiel).

So kann der Compiler nicht einmal lassen Sie die Zukunft erklären die Enum und Benutzer einen Zeiger auf sie, denn auch dort ist es die Größe des Aufzählungs muss.

Sie definieren eine Aufzählung der möglichen Werte der Elemente des Typs auf einen begrenzten Satz zu beschränken. Diese Einschränkung wird bei der Kompilierung durchgesetzt werden.

Wenn sie darauf, die Tatsache zu erklären, dass Sie eine ‚begrenzte Menge‘ verwenden werden später hinzufügen, keinen Wert. Nachfolgender Code, um die möglichen Werte, um davon zu profitieren wissen muss,

Obwohl der Compiler ist besorgt über die Größe des Aufzählungstyp, der Absicht der Aufzählung geht verloren, wenn Sie darauf, es erklären.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top