Typedef in Eigenschaften vs. typedef in der Klasse

9

Ich schaue den Eigenen Quellcode für Bildungszwecke durch. Ich habe festgestellt, dass für jede konkrete Klassenvorlage X in der Hierarchie ein internal::traits<X> definiert ist. Ein typisches Beispiel finden Sie in Matrix.h:

%Vor%

Ich verstehe jetzt, dass Eigenschaften eine Möglichkeit darstellen, vorhandene Klassen zu erweitern, die Sie nicht mit zusätzlichen Informationen zu einem neuen Code ändern möchten. Zum Beispiel könnte ein Benutzer der Klassenvorlage Foo<class TAllocator> die vorhandenen Speicherzuordner FastAlloc und AlignedAlloc verwenden wollen, aber Foo muss wissen, wie man mit diesen beiden interagiert, und so ein FooTraits<AlignedAlloc>::allocate() und FooTraits<FastAlloc>::allocate() werden vom Benutzer definiert, die wiederum von Foo verwendet werden.

In diesem Fall sehe ich jedoch nicht ohne weiteres das Problem, nur Scalar in jeder abgeleiteten Klasse anzugeben, d. h. Matrix define Matrix::Scalar mit einem typedef im Klassenkörper. Was ist der Vorteil einer Traits-Klasse? Ist es nur für den Zweck, den Code sauber zu halten, d. H. Alle relevanten Eigenschaften jeder Klasse in der Merkmalsklasse zu speichern?

Bearbeiten Sie gemäß Nicol Bolas Antwort: Ich verstehe, dass einige dieser typedefs möglicherweise "intern" gehalten werden müssen, d. h. sollten nicht dem Benutzer ausgesetzt werden, was die Merkmalsklasse erklären würde. Das scheint sinnvoll zu sein, jedoch sind einige dieser Typdefinitionen wie Scalar , für die Außenwelt über einen typedef in der Basisklasse von Matrix :

verfügbar %Vor%

Das bringt uns zu der ursprünglichen Frage zurück: Warum ist Scalar nicht nur ein typedef in Matrix selbst? Gibt es einen Grund neben der stilistischen Wahl?

    
Moos Hueting 24.08.2016, 20:46
quelle

2 Antworten

6

Ich vermute, dass, da die Merkmalsklasse internal ist, dies der Punkt ist, eine Merkmalsklasse zu verwenden. Das heißt, diese Dinge intern zu behalten. Auf diese Weise hat Matrix selbst in seiner privaten Schnittstelle nicht viele Oddball-Definitionen und so weiter.

Betrachten Sie die Aufzählung in Ihrem Beispiel. Diese "enums" (aka: static constexpr Variablen vor C ++ 11) sehen nicht wie etwas aus, was ein Benutzer wissen sollte. Es ist ein Implementierungsdetail und daher sollte es versteckt werden.

Das Problem von

MatrixBase ist ein CRTP-Problem.

Siehe Matrix würde wie folgt definiert:

%Vor%

Diese partielle Definition bewirkt, dass zwei Dinge passieren:

  1. Wenn Matrix noch nicht als Klassentyp deklariert wurde, wird es zu einer legalen Klasse, auf deren Namen verwiesen und verwendet werden kann.

  2. Die Vorlage MatrixBase muss mit dem Typ Matrix instanziiert werden. Jetzt gerade .

Das Problem ist, dass "gerade jetzt", Matrix eine unvollständige Klasse ist. Der Compiler ist noch nicht in den Rumpf dieser Definition eingetreten, so dass der Compiler nichts über seine Interna weiß. Aber MatrixBase muss gerade instanziiert werden.

Daher kann MatrixBase keinen der Inhalte der Klasse Derived verwenden, für die sie bereitgestellt wird. Wenn Matrix eine Art typedef enthält, kann MatrixBase<Derived> sie nicht sehen

Jetzt können Elementfunktionen von MatrixBase<Derived> Definitionen in Derived betrachten, da diese definiert sind, nachdem die vollständige Klasse definiert wurde. Auch wenn diese Funktionen im Rahmen der Klasse definiert sind.

Sie können jedoch keine Eigenschaften von MatrixBase access properties von Derived haben. Daher die Charaktereigenschaften Indirection. Die Merkmalsklasse kann eine Spezialisierung basierend auf einem unvollständigen Typ verwenden, um Definitionen für MatrixBase verfügbar zu machen.

    
Nicol Bolas 24.08.2016, 21:42
quelle
3

Der Hauptgrund für diese traits -Klasse ist, rekursive Abhängigkeiten im CRTP zu vermeiden. Ohne es würden wir mit etwas enden wie:

%Vor%

kann unter bestimmten Umständen nicht kompiliert werden. Grundsätzlich erlaubt diese Klasse traits , Base<Matrix> vollständig zu deklarieren, ohne die Deklaration von Matrix zu kennen.

    
ggael 24.08.2016 22:10
quelle

Tags und Links