2012-05-26 51 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

相关问题