2013-06-06 30 views
13

Jakie jest najlepsze rozwiązanie do forwardowania deklaruj typedef w klasie. Oto przykład tego, co trzeba rozwiązać:Przekaż zadeklaruj typedef w klasie C++

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(); 
}; 

Przypuszczam, że po prostu wykonaj następujące czynności:

boost::shared_ptr<B> foo(); 

Ale tam jest bardziej eleganckie rozwiązanie?

+0

IMO jesteś podtytułowany, aby wykonać typedefs wokół linii 3, przynajmniej jednego z nich. Lub użyj innego typedef i sprawdź później za pomocą static_assert i is_same_type później dla spójności. –

Odpowiedz

12

Nie ma czegoś takiego jak forward, który niestety deklaruje typedef. Jest jednak pewna sztuczka z wykorzystaniem późnego tworzenia instancji:

template <typename T> class BImpl; 

template <typename T> 
class AImpl 
{ 
public: 
    typedef boost::shared_ptr<AImpl> Ptr; 
    typename BImpl<T>::Ptr foo(); 
}; 

template <typename T> 
class BImpl 
{ 
public: 
    typedef boost::shared_ptr<BImpl> Ptr; 
    typename AImpl<T>::Ptr bar(); 
}; 

typedef AImpl<void> A; 
typedef BImpl<void> B; 

Powinno to mieć nadzieję, że uda się osiągnąć cel, do którego dążysz.

+2

Również tego chciałem. – John

+1

Dzięki, wygląda całkiem dobrze! – Tom

1

Nie ma sposobu, aby przekazać deklarują albo

  1. A typedef
  2. nazwę w innej klasie

SO - nie można do przodu zadeklarować typedef i gdybyś mógł, nadal nie byłby w stanie tego zrobić, ponieważ musiałbyś to zrobić:

class B::Ptr; 

i to nie jest możliwe

2

Nie możesz.

Ale można oddzielić definicję PTR klas:

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(); 
}; 

Jeżeli A i B nie mają te same typy, zawsze mogą specjalizować Cechy dla wszystkich typów.

4

pan stoi dwa różne trudności: 1. Brak terminowe deklaracje typedefs 2. Oświadczenia przodu zagnieżdżonych typów nie są możliwe

Nie ma sposobu, wokół drugi: trzeba unnest typy.

Jednym ze sposobów wokół pierwszego, który czasami używam, jest utworzenie typu pochodnego, a tak, może być zadeklarowane w przód.

Powiedz:

struct Ptr : shared_ptr<A> {}; 

Jest to nowy typ, ale to jest prawie taka sama jak synonim. Problemem są oczywiście konstruktorzy, ale w C++ 11 jest coraz lepiej.

Ta odpowiedź jest ogólnie rzecz biorąc. W twoim konkretnym przypadku, myślę, że powinieneś zdefiniować Ptr poza klasami i nie miałbyś żadnego problemu.

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

a następnie zajęcia.

1

Jak zauważyli inni, nie można przekazywać dalej - deklaruj typedefs.Częściowo dlatego, że typedefs nie są tak naprawdę "typami" własnymi, ale aliasami dla innych typów (stąd ekwiwalent C++ 11 "aliasu typu" takiego jak "używając Int = int;"). Oznacza to na przykład, że typy nie pojawiają się w elementach ABI, takich jak zniekształcone nazwy, a więc kompilator naprawdę musi znać wystarczającą ilość podstawowego typu, aby spełnić wszystkie wymagania ABI (w tym, jak zmienić nazwę typu).