假设我有以下课程:
template <class T,class U,class V> Foo { ... };
模板参数具有不同的映射,因此我可以根据T是什么推断出其他模板参数U和V.例如,如果T为double,则U和V将始终为某些类D1和D2,如果T为float,则U和V将始终为其他类F1和F2.
考虑到这一点,有没有一种方法可以只传递一个模板参数,并让编译器推导出另外两个参数?
我知道简单的答案就是将这些其他类也模板化并将模板参数T传递给它们,但我无法将这些类模板化(它们是由工具自动生成的).
理想情况下,我可以像这样使用typedef或#define:
typedef Foo<double> Foo<double,D1,D2> typedef Foo<float> Foo<float,F1,F2>
但是这些不能编译.我想知道是否有办法使用模板元编程或模板模板参数来解决这个问题,但我似乎无法将这些概念包裹起来,我有一种直觉,那里可能有更简单的答案.有人有什么想法吗?
解决方法
Angew给出的答案向您展示了正确的方法,但没有向您展示如何应对U和V无法推断并且必须由实例化客户端提供的情况.
要处理这种情况,您可以为模板参数U和V分配默认参数:
struct D1 { }; struct D2 { }; struct F1 { }; struct F2 { }; // Primary template template<typename T> struct deduce_from { }; // Specialization for double: U -> D1,V -> D2 template<> struct deduce_from<double> { typedef D1 U; typedef D2 V; }; // Specialization for float: U -> F1,V -> F2 template<> struct deduce_from<float> { typedef F1 U; typedef F2 V; }; // Give defaults to U and V: if deduce_from is not specialized for // the supplied T,and U or V are not explicitly provided,a compilation // error will occur template< typename T,typename U = typename deduce_from<T>::U,typename V = typename deduce_from<T>::V > struct Foo { typedef U typeU; typedef V typeV; };
这是一个简单的程序来测试上述解决方案的正确性:
#include <type_traits> int main() { static_assert(std::is_same<Foo<double>::typeU,D1>::value,"Error!"); static_assert(std::is_same<Foo<double>::typeV,D2>::value,"Error!"); static_assert(std::is_same<Foo<float>::typeU,F1>::value,"Error!"); static_assert(std::is_same<Foo<float>::typeV,F2>::value,"Error!"); // Uncommenting this will give you an ERROR! // No deduced types for U and V when T is int /* static_assert( std::is_same<Foo<int>::typeU,void>::value,"Error!" ); */ static_assert( std::is_same<Foo<int,bool,char>::typeU,bool>::value,"Error!" ); // OK static_assert( std::is_same<Foo<int,char>::typeV,char>::value,"Error!" ); // OK }