2014-11-13 4 views
2

주어진 템플릿 인수에 대해 Qt typedef 별칭을 거의 만들지 않는 도우미 클래스를 사용하고 싶습니다. Ofc ambiguous는 십자가를 매우 빨리 그리고 심지어는 현재과 Derived에 액세스하기를 원하기 때문에 프로젝트의 현재 디자인 상황에 자주 등장합니다. 이 문제가 어떻게 든 해결할 수있는 것인지 확실하지 않아도 여전히 문제를 해결할 수 있습니다. 예 :모호한 문제 피하기 C++

template <class T> class SmartAlias 
{ 
public: 
    typedef QSharedPointer<T> Shared; 
}; 

class Base : public SmartAlias<Base> 
{ 
}; 

class Derived : public Base, public SmartAlias<Derived> 
{ 
}; 

Base::Shared base; // Normally works 
Derived::Shared derived; // ambiguous problem 

더 좋은 해결책이 있습니까? 감사.

요약/UPDATE/솔루션

하나는이를 사용하고자하는 경우, 또한 가상 상속을 사용하여 다중 상속을 위해 확장 될 수 안톤 아버님 께 구원 아이디어로 이동, 그것을 요약하면 :

#include <vector> 

template <typename T, typename... MyBases> class SmartAlias : virtual public MyBases... { 
public: 
    typedef std::vector<T> Shared; 
}; 

class Base : public SmartAlias<Base> 
{ 
}; 

class Derived : public SmartAlias<Derived, Base> 
{ 
}; 

class MiniBase : public SmartAlias<MiniBase> {}; 

class MiniDerived : public SmartAlias<MiniDerived, MiniBase, Derived> { 
public: 
    MiniDerived() : MiniBase(), Derived() 
    { 
    } 
}; 

int main() { 
    Base::Shared base; 
    Derived::Shared derived; 
    MiniDerived::Shared md; 
} 

다른 한편으로는 Frerich Raabe가 언급 한 나의 현재 해결책을 고수 할 것입니다.

답변

2

명시 적으로 두 개의 Shared의 당신이 사용하고자하는 Derived에 지정할 수 있습니다 여기에

class Derived : public Base, public SmartAlias<Derived> 
{ 
public: 
    using Shared = SmartAlias<Derived>::Shared; 
    // or in pre-C++11 
    typedef SmartAlias<Derived>::Shared Shared; 
}; 

모든 클래스 형식 정의를 추가 할 필요가 없습니다 또 다른 옵션입니다. 인터페이스 재사용이 항상 나를 긴장하게하는 대신 코드 재사용 (공개) 상속을 사용하는 코드를보고, 솔직히

template <typename T, typename MyBase = void> class SmartAlias : public MyBase 
{ 
public: 
    typedef typename SmartAlias<T>::Shared Shared; 
}; 

template <typename T> class SmartAlias<T, void> 
{ 
public: 
    typedef QSharedPointer<T> Shared; 
}; 

class Base : public SmartAlias<Base> 
{ 
}; 

class Derived : public SmartAlias<Derived, Base> 
{ 
}; 
+0

'Shared'앞에 예상되는 중첩 이름 지정자를 컴파일하지 않습니다. 인터넷 검색 ... – krizajb

+0

pre-C++ 11에서 @krizajb 대신에'typedef'를 사용해야합니다 –

+0

멋진 작품이지만 물건을 쓸모 없게 만듭니다 :) – krizajb

0

문제는 파생 된 개체를 생성 할 때 SmartAlias에 대한 개체를 생성하고 인과 관계에서 파생 된 SmartAlias를 의도적으로 파생시키는 Base 개체를 인턴으로 생성하는 것입니다. 따라서 하나의 Derived 객체에 2 개의 SmartAlias ​​객체가 있습니다. 파생 된 객체를 사용하여 SmartAlias의 멤버에 액세스하려면 모호하게됩니다. 따라서 SmartAlias를 Derived의 즉각적인 기반으로 삼지 않아도됩니다.

+0

나는 마지막 문장을 이해하지 못한다. 나는 실제로 어떤 미친 아이디어를 내고있다. :) – krizajb

+0

클래스 Derived : public Base { }; 충분하다. – Venkatesh

+1

위의 예제 코드를 사용하고 싶지는 않습니다. – krizajb

2

대신 그것은 SmartAliasBase 사이 Derived를 삽입 계층 구조를 수정합니다. 그리고 그 이름에 '똑똑한'클래스가 거의 코드 냄새입니다. 어때 그냥

class Base 
{ 
public: 
    typedef QSharedPointer<Base> Shared; 
}; 

class Derived : public Base 
{ 
public: 
    typedef QSharedPointer<Derived> Shared; 
}; 
+0

이것은 현재 디자인입니다. 더 쉽게 만들고 재사용 가능한 코드를 만들려고 노력했을뿐입니다. 아시다시피, 거기에 다른 스마트 포인터가 많이 있습니다 :) – krizajb