2011-09-08 4 views
9

다음 구조를 가진 클래스 집합이 있습니다.유형 목록에서 상속하고 상속 된 멤버 목록에서 멤버를 호출하는 방법?

class U 
{ 
public: 
    explicit U(int) { ... } 
    U() {...} 
    Init(int) {...} 
}; 

이 클래스 중 하나 이상을 클래스 X로 작성할 수 있어야합니다. 의사 코드 :

template<class TypeSequence> 
class X that derives publicly from all the classes in TypeSequence 
{ 
    X(int): all bases are initialized with the integer passed 
    {} 
    //if the above constructor is impossible, then the following will do as well: 
    X(int) 
    { 
     Call Init on all bases and pass the given int to them. 
    } 
}; 

mpl이 많이 필요하지만 실제로 잘하지 않습니다. 내가 할 수있는 일은 무엇입니까? 코드 샘플은 훌륭합니다.

내 오류 : 언급을 잊어 버렸습니다. C++ 11 기능을 사용할 수 없습니다. MPL 솔루션을 찾고 있습니다.

+0

+1 좋은 질문을. 그런데 믹스 인에 대해 들어 보셨습니까? 어쩌면 여기에 적용 할 수 있습니까? 아니면 그 변형 일 수 있습니까? – Nawaz

+0

이전에 [Boost.MPL] (http://www.boost.org/libs/mpl/)을 사용하여이 작업을 수행했지만 코드를 작성하지 않아도됩니다. 지금 당장 풀 답변. 아무도 그때까지 대답하지 않으면 나는 오늘 밤 이것을 다시 살펴볼 것입니다. 힌트로서, 템플릿 인자로 두 개의 'boost :: mpl :: vector <>'이터레이터를 취하는 특별한 믹스 인을 생각해 낸다. – ildjarn

+0

U는 TypeSequence와 어떤 관련이 있습니까? –

답변

5

음, Boost.MPL에는 메타 기능이 포함되어 있습니다. inheritinherit_linearlyfor_each과 결합하여 두 번째 변형 (init 함수 사용)을 얻을 수 있습니다.

#include <iostream> 
#include <boost/mpl/fold.hpp> 
#include <boost/mpl/vector.hpp> 

struct A 
{ 
    A(int x) { std::cout << "A::A " << x << std::endl; } 
}; 

struct B 
{ 
    B(int x) { std::cout << "B::B " << x << std::endl; } 
}; 

struct C 
{ 
    C(int x) { std::cout << "C::C " << x << std::endl; } 
}; 

int main() 
{ 
    InheritFrom_IntConstructor< boost::mpl::vector<A, B, C> >(1); 
} 

Metafunction InheritFrom_IntConstructor가 생성자 매개 변수로 임의의 유형을 받아 일반화 할 수 있으며 일반 캔의 임의의 수를 받아 들일 경우 잘 모르겠어요 :

struct Null_IntConstructor 
{ 
    Null_IntConstructor(int) { } 
}; 

struct InheritFrom_IntConstructor_Folder 
{ 
    template<typename T1, typename T2> 
    struct apply 
    { 
    struct type : T1, T2 
    { 
     type(int x) : T1(x), T2(x) { } 
    }; 
    }; 
}; 

template<typename Bases> 
struct InheritFrom_IntConstructor 
    : boost::mpl::fold<Bases, 
        Null_IntConstructor, 
        InheritFrom_IntConstructor_Folder>::type 
{ 
    InheritFrom_IntConstructor(int x) 
    : boost::mpl::fold<Bases, 
         Null_IntConstructor, 
         InheritFrom_IntConstructor_Folder>::type(x) 
    { } 
}; 

사용 예 : 아니면 그냥 boost::mpl::fold 및 사용자 정의 메타 기능을 사용하여 인수.

+0

+1 : 테스트 중입니다. :) –

+0

@Begeoth : 완벽하게 작동합니다. 나는 정확히 '폴드'가 무엇인지 살펴볼 필요가 있지만, 대단히 감사합니다. –

+0

@Armen :'mpl :: fold'은 제 솔루션에서했던 것과 거의 똑같습니다. – Nawaz

1

뭔가 작동합니다. 인스턴스 당 사용되지 않는 기본 유형 당 최대 1 바이트를 낭비해야합니다.

template<int> 
class PlaceHolder { PlaceHolder(int){} }; 

template< 
     class typeOne, 
     class typeTwo=PlaceHolder<2>, 
     class TypeThree=PlaceHolder<3>, 
     class TypeFour=PlaceHolder<4>, 
     class TypeFive=PlaceHolder<5> 
     > 
class X : 
     public typeOne, 
     public typeTwo, 
     public typeThree, 
     public typeFour, 
     public typeFive 
{ 
    X(int b) 
    : typeOne(b), 
    typeTwo(b), 
    typeThree(b), 
    typeFour(b), 
    typeFive(b) 
    {} 

    X(const X& b) 
    : typeOne(b), 
    typeTwo(b), 
    typeThree(b), 
    typeFour(b), 
    typeFive(b) 
    {} 

    X& operator=(const X& b) { 
     typeOne::operator=(b); 
     typeTwo::operator=(b); 
     typeThree::operator=(b); 
     typeFour::operator=(b); 
     typeFive::operator=(b);} 
     return *this; 
    } 
}; 
+0

다른 템플릿 인수로 같은 템플릿을 가질 수 없습니다 숫자 –

+0

괜찮아요, 템플릿 이름을 변경하고 단 하나의 이름으로 작동하지만 공간을 낭비 할 수있는 버전을 추가했습니다. –

+1

나는 솔직히 당신의 해결책을 좋아하지 않지만, 당신이 저를 도우려고 시간을 보냈기 때문에 그것을 상향 투표했습니다. 감사합니다 –

3

이와 비슷한?

template <typename ...BaseClasses> 
class Aggregator : public BaseClasses... 
{ 
public: 
    Aggregator(int i) : BaseClasses(i)... 
    {} 

}; 

사용 예 :

Aggregator<U, V, W> a(10); 
Aggregator<U, V> b(15); 
Aggregator<W> c(20); 

참고 : 가변 인자 템플릿을 사용하기 때문에 C++ (11)가 필요합니다.

+2

+1 : 이것은 깨끗하고 단순한 soooo입니다. 고맙습니다. 불행하게도, *** 불행히도 *** 가변적 인 템플릿을 사용할 수 없다 : ( –

+0

'BaseClasses (i) ...'작동 하는가? § 14.5.3/5는 그것을 읽는 것으로 보인다! 깔끔함! –

+0

C + +11 표현력. 원본 질문을 임의의 유형 생성자 인수 임의의 수로 일반화하려는 경우 – Begemoth

2

나는 부스트를 사용하지 않고 있으며, 내 솔루션이 얼마나 필요한지 잘 모르겠습니다. 코드를 테스트 한 후

template<typename typeseq> 
struct X : typeseq::head, X<typename typeseq::tail> 
{ 
    typedef typename typeseq::head base; 
    typedef X<typename typeseq::tail> recursebase; 
    X(int i) : base(i), recursebase(i) {} 
    void init(int i) 
    { 
     base::init(i); 
     recursebase::init(i); 
    } 
}; 

template<> 
struct X<null_type> 
{ 
    X(int i) {} 
    void init(int i) { } 
}; 

을 그리고 :하지만 여전히 나는 그것을 게시하도록하겠습니다

typedef typelist<S,typelist<U>> typeseq; 
X<typeseq> x(10); 
x.init(100); 

온라인 데모 : http://ideone.com/e6tuM

+0

좋은 일이지만, 재사용하는 mpl이 더 깨끗하다는 것을 인정합니다. –

+0

Begemoth의 대답을 보았을 때, 이것은 나에게도 일어 났고 나는 그것을 게시하려했습니다. 당신은 더 빨랐다 : D 웨이는 나의 원본보다 더 잘 대답했다. –

관련 문제