2013-06-06 8 views
13

Was ist die beste Lösung, um eine typedef innerhalb einer Klasse weiterzuleiten. Hier ist ein Beispiel dafür, was ich brauche, zu lösen:Vorwärts declare typedef in C++ - Klasse

class A; 
class B; 

class A 
{ 
    typedef boost::shared_ptr<A> Ptr; 

    B::Ptr foo(); 
}; 

class B 
{ 
    typedef boost::shared_ptr<B> Ptr; 

    A::Ptr bar(); 
}; 

Ich glaube, ich könnte nur Folgendes tun:

boost::shared_ptr<B> foo(); 

Aber gibt es eine elegantere Lösung?

+0

IMO du bist abgespritzt, um die Typedefs um Linie 3, mindestens eine von ihnen zu tun. Oder verwenden Sie einen anderen typedef und überprüfen Sie es später mit static_assert und is_same_type später auf Konsistenz. –

Antwort

12

Es gibt keine solche Sache, wie eine typedef nach vorne zu deklarieren leider. Es gibt jedoch einen Trick bei der Instanziierung später Instances:

Dies sollte hoffentlich das erreichen, was Sie anstreben.

+2

Ich wollte es auch schon mal haben. – John

+1

Danke, das sieht gut aus! – Tom

1

gibt es keine Möglichkeit entweder

  1. Einen typedef
  2. Einen Namen in einer anderen Klasse zu übermitteln erklären

So - Sie nicht nach vorne ein typedef erklären können und wenn Sie könnten, haben Sie immer wäre nicht in der Lage, das zu tun, weil Sie dies tun müssten:

und das ist nicht möglich

2

Sie können nicht.

Aber Sie können die Ptr Definition der Klassen entkoppeln:

class A; 
class B; 

template <typename T> 
struct Traits { 
    typedef std::shared_ptr<A> Ptr; 
}; 

class A 
{ 
    Traits<B>::Ptr foo(); 
}; 

class B 
{ 
    Traits<A>::Ptr bar(); 
}; 

Wenn A und B nicht die gleichen Typen nicht teilt, kann man immer Traits spezialisiert für alle Arten.

4

Sie sind mit Blick auf zwei verschiedene Schwierigkeiten: 1. Es gibt keine Terminerklärungen typedefs 2. Vorwärtsdeklarationen von verschachtelten Typen sind nicht möglich

Es gibt keine Möglichkeit, um die zweite: Sie haben die UNNEST Arten.

Ein Weg um den ersten, den ich gelegentlich verwende, ist, einen abgeleiteten Typ zu machen, und der ja, kann vorwärts erklärt werden.

Sprich:

struct Ptr : shared_ptr<A> {}; 

Dies ist eine neue Art ist, aber es ist fast das gleiche wie ein Synonym. Das Problem ist natürlich, Konstruktoren, aber das wird besser mit C++ 11.

Diese Antwort ist natürlich im Allgemeinen. Für Ihren speziellen Fall, denke ich, sollten Sie die PTRs außerhalb der Klassen definieren und Sie würden überhaupt kein Problem haben.

struct A; 
struct B; 
typedef shared_ptr<A> APtr; 
typedef shared_ptr<B> BPtr; 

und dann die Klassen.

1

Wie andere bemerkt haben, können Sie typedefs nicht weiterleiten.Das liegt zum Teil daran, dass typedefs nicht wirklich "Typen" sind, sondern Aliase für andere Typen (daher die C++ 11-äquivalente Vorstellung eines "type alias" wie "using Int = int;"). Das bedeutet zum Beispiel, dass typedefs nicht in ABI-Elementen wie Mangled-Namen auftaucht, und der Compiler wirklich genug vom zugrundeliegenden Typ wissen muss, um alle ABI-Anforderungen zu erfüllen (einschließlich, wie man den Typnamen ändert).