2012-05-26 78 views
2

我有一個類C這是模板A<W>B<W>。現在在C中,我想要構造一個類型爲A<U>B<U>的對象,具體取決於它實例化的內容。如何在收到Foo <S>後構造Foo <T>?

如果這聽起來有點怪,考慮下面的代碼,並在它的評論:

template<class W> 
struct A { 
    typedef A type; 
}; 

template<class W> 
struct B { 
    typedef B type; 
}; 

template<class AB> 
struct C { 
    // AB is A or B. If it's A we want to construct A<double>, if it's B               
    // we want to construct B<double>:                        
    typedef typename AB::type type; // A or B                      
    typename type<double> D; // ERROR 
    D d; 
}; 

int main(int argc, char** argv){ 
    C<A<int> > c1; 
    C<B<int> > c2; 
} 

有沒有辦法做到這一點?

我認爲C需要模板化嵌套模板,但我不知道該怎麼做。

回答

2

要做到這一點,你需要局部模板規格:

// base declaration is undefined 
template< typename AorB > struct C; 

// declaration for A<W> 
template< typename W > 
struct C< A<W> > 
{ 
    typedef A<double> type; 
}; 

// declaration for B<W> 
template< typename W > 
struct C< B<W> > 
{ 
    typedef B<double> type; 
}; 

與一個類型參數的任何模板類的工作方式更普遍的情況是:

// base declaration is undefined 
template< typename AorB > struct C; 

// declaration for T<W> 
template< template<typename> class T, typename W > 
struct C< T<W> > 
{ 
    typedef T<double> type; 
}; 
+0

啊,這就是我在腦子裏,當我說用它或許可以得到解決嵌套模板。太好了! – Frank

3

這可以通過解決引入一個幫助模板,我在下面的代碼中命名爲translate

template<class W> 
struct A { 
    typedef A type; 
}; 

template<class W> 
struct B { 
    typedef B type; 
}; 

template<class AB, class U> 
struct translate { 
}; 

template<template<typename> class AB, class W, class U> 
struct translate<AB<W>, U> { 
    typedef AB<U> type; 
}; 

template<class AB> 
struct C { 
    // AB is A or B. If it's A we want to construct A<double>, if it's B               
    // we want to construct B<double>:                        
    typedef typename translate<AB, double>::type D; 
    D d; 
}; 

int main(int argc, char** argv){ 
    C<A<int> > c1; 
    C<B<int> > c2; 
} 
+0

好方法。它不需要修改原來的類;同樣,使用可變參數模板,您可以重新綁定任何模板類型(不僅僅是隻有1個參數的模板,就像OP的情況一樣) – sbabbi

3

另一種選擇是要做得像分配器,並提供一個rebind模板AB裏面,如果你有機會到那些:

template<class T> 
struct A{ 
    template<class U> 
    struct rebind{ typedef A<U> other; }; 
}; 

template<class AB> 
struct C{ 
    typedef typename AB::template rebind<double>::other rebound_AB; 
}; 
+0

Nifty!之前沒有看到過這種模式。 – reima

相關問題