请提前警告:这个问题似乎比实际问题更加明显。
我想编写一个可以接受任何具体类或模板类作为模板参数的模板。这似乎没有用,因为不知道传入的T是否已模板化,您将不知道如何使用它。我想要这样做的原因是,我可以声明一个没有定义的通用模板,然后由用户进行专门化。因为用户正在专门研究它,所以他们总是知道他们要处理的类型。但是,如果不先声明模板,用户将无法对其进行专门化处理。
您可以这样做:
template<class T>
class myclass;
但是,如果您传入模板化的T,那将不起作用,例如
myclass<std::vector>
将不起作用。因此,我们尝试以下操作:template<class T>
class myclass;
template<template<class> T>
class myclass;
这可能是正确的方法,但是由于类模板不能被重载,因此无法正常工作。因此,让我们将其切换为功能模板,可以是:
template<class T>
void myfunc();
template<template<class> T>
void myfunc();
亲爱的,所以我们做对了吗?嗯,可能给模板template参数提供了不同数量的参数,因此我们也需要考虑到这一点。
template<class T>
void myfunc();
template<template<class> T>
void myfunc();
template<template<class, class> T>
void myfunc();
template<template<class, class, class> T>
void myfunc();
// etc.
难看,但是Boost Preprocessor Library可以为我们生成此代码(并且在C++ 0x中将添加对可变参数模板的支持,因此,此丑陋只是暂时的)。但是我们仍然忘记了一个案例!如果T的参数之一不是一个类,而是一个常量整数,该怎么办?让我们支持一下:
template<class T>
void myfunc();
template<template<class> T>
void myfunc();
template<template<class, class> T>
void myfunc();
template<template<class, class, class> T>
void myfunc();
// etc.
template<template<class> T>
void myfunc();
template<template<class, int> T>
void myfunc();
template<template<int, class> T>
void myfunc();
template<template<int, class, class> T>
void myfunc();
template<template<class, int, class> T>
void myfunc();
template<template<class, class, int> T>
void myfunc();
// etc.
哦哦鉴于任何常量类型都可以传入任意数量的模板中,并与类参数混合使用,KABLOOEY组合爆炸。只是为了使事情变得更困难,如果T的任何参数本身就是模板,该怎么办?
最佳答案
boost::mpl做类似的事情(这是binding an argument的想法)。但是,您必须做出很多假设才能使其正常工作,例如使用;
template <class T> foo { }; typedef foo< int_<4> > my_foo_4;
代替
template <int T> foo { }; typedef foo<4> my_foo_4;
不必为所有int,char,bool等组合提供重载。
我想不出任何比boost::mpl方法更有效的方法,总的来说,我认为任何方法都会遇到很多问题。一个类模板不是一个类型,并且不能以这种方式真正嵌入到类型系统中(boost::mpl将其视为创建新类型的函数;更一般而言,它用于创建“MetaFunction”) 。我什至不确定可变参数模板是否会影响模板模板参数(尽管有趣的问题)。