6 Stimmen

Was ist der Sinn von "typedef sometype sometype"?

In letzter Zeit bin ich auf die folgende Konstruktion im Code gestoßen:

typedef sometype sometype;

Achten Sie bitte darauf, dass "sometype" für den absolut gleichen Typ steht, ohne irgendwelche Zusätze wie "struct" etc.

Ich frage mich, wozu es nützlich sein kann?

UPD: Dies funktioniert nur bei benutzerdefinierten Typen.

UPD2: Der eigentliche Code befand sich in einem Vorlagenkontext wie diesem:

template <class T>
struct E
{
   typedef T T;
   ...
}

7voto

Kaz Dragon Punkte 6406

Wie wäre es, wenn Sie die Parameter der Vorlage für Außenstehende sichtbar machen würden?

template <class Foo>
struct Bar
{
    typedef Foo Foo;
};

int main()
{
    Bar<int>::Foo foo = 4;
}

Hinweis: Dies ist in Standard-C++ nicht erlaubt, sondern ist spezifisch für MSVC. Siehe Kommentare.

7voto

Konrad Rudolph Punkte 503837

Aufgrund Ihrer zusätzlichen Informationen über Vorlagen können wir nun antworten.

Der Anwendungsfall ist, wenn Sie sich auf den Typ einer Vorlage spezialisieren wollen. Ein typisches Beispiel ist das folgende:

template <typename T>
struct nonconst {
    typedef T t;
};

template <typename T>
struct nonconst<T const> {
    typedef T t;
};

Auf diese Weise können Sie die const Qualifier von cualquier Typ:

nonconst<int>::t x;
nonconst<int const>::t y;
assert(typeid(x) == typeid(int));
assert(typeid(y) == typeid(int));

Es gibt viele ähnliche Anwendungsfälle, z. B. das Hinzufügen (oder Entfernen) des Zeigerqualifizierers aus einem Typ, das Bereitstellen von Standardwerten und Spezialisierungen für bestimmte Typen usw.

Allerdings, Beachten Sie das unterschiedliche Gehäuse der Typennamen! Gleiche Typen in typedef T T sind illegale C++. [Ich habe mich korrigiert: §7.1.3.2] Darüber hinaus ist der de-fact-Namensgebungsstandard (zementiert durch seine Verwendung in Boost-Bibliotheken), den Typnamen alias zu nennen type , z.B.:

typedef T type;

6voto

Douglas Leeder Punkte 50423

In C++ kann ein Typedef in einen Namespace oder eine Klasse eingefügt und dann relativ zu diesem Namespace oder dieser Klasse referenziert werden, was nützlich sein kann, wenn sich der tatsächliche Typ in Zukunft ändern könnte.

z.B..

class IntHolder
{
    public:
        typedef int int;
        IntHolder::int i;
};
...
IntHolder foo;
IntHolder::int i = foo.i;

(NB: Ich habe nicht überprüft, ob das die richtige Syntax ist - aber ich hoffe, Sie verstehen die Idee)

Wenn Sie zu einem späteren Zeitpunkt tatsächlich die long en IntHolder müssen Sie nur die IntHolder Code.

Normalerweise benennen Sie den Typ anders, aber vielleicht können Sie es wie oben machen?

6voto

Notinlist Punkte 15635

Ich habe eine Theorie. Es könnte ein Ergebnis von einigen Refactorings sein. Zum Beispiel eine Vorlage Typ werden nicht schablonenhaft.

typedef SomeCleverTemplate<Rocket> SuperThing;

Dann löschten sie die Vorlage, da sie im Code nicht mehr verwendet wurde, und ersetzten sicherheitshalber alle SomeCleverTemplate<Rocket> a SuperThing .

typedef SuperThing SuperThing;

Ergibt das im realen Kontext Sinn?

1voto

Matthieu M. Punkte 266317

Wie bereits erwähnt, funktioniert es besonders gut innerhalb einer Vorlage:

template <class Foo>
struct Bar
{
  typedef Foo Foo;
};

Sie kann aber auch mit einer Vorlagenspezialisierung kombiniert werden:

template <class Foo>
struct Bar<Foo*>
{
  typedef Foo Foo;
};

Das kann ich tun:

Bar<int>::Foo i = 0;
Bar<int*>::Foo j = i;

Bar verhält sich somit effektiv wie eine Art Typumhüllung, was für seine Schnittstelle wichtig sein kann (wenn es eine bool equals(Foo i) const zum Beispiel).

In der Regel hat der gewählte Name eine bestimmte Bedeutung value_type zum Beispiel...

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X