通过模板参数号重载模板类
Posted
技术标签:
【中文标题】通过模板参数号重载模板类【英文标题】:Overloading template classes by template parameter number 【发布时间】:2011-10-22 17:59:15 【问题描述】:同一类是否可以有多个版本,它们的区别仅在于它们采用的模板参数的数量?
例如:
template<typename T>
class Blah
public:
void operator()(T);
;
template<typename T, typename T2>
class Blah
public:
void operator()(T, T2);
;
我正在尝试对函子类型的事物进行建模,这些事物可以接受可变数量的参数(最多可写出的不同模板的数量)。
【问题讨论】:
我想知道你是否可以用类型列表做点什么。 @john 那是个好主意,但我使用的 MSVC++ 2010 不支持它们,我不相信。 实际上 boost::tuple 可能是同一想法的更易于访问的版本。有一个具有一种类型的通用模板,然后是具有两种、三种、四种类型的元组的专用版本。 【参考方案1】:最简单的答案是只有一个模板,其中包含您想要支持的最大数量,并在除第一种类型之外的所有类型上使用 void 作为默认类型。然后您可以根据需要使用部分特化:
template<typename T1, typename T2=void>
struct foo
void operator()(T1, T2);
;
template <typename T1>
struct foo<T1, void>
void operator()(T1);
;
int main()
foo<int> test1;
foo<int,int> test2;
test1(0);
test2(1,1);
【讨论】:
如果某些类型是void
,我认为operator()(T, T2, T3, T4)
的定义不会正确。
@ben - 它不是那样工作的,因此部分专业化有效地给出了模板参数数量的“重载”
好的,谢谢,使用部分模板专业化技巧它可以工作。非常感谢,我会在 6 分钟内将此标记为答案。
@awoodland:这看起来不错。当我评论它时,比你的答案要好得多。
@Nikolai:提问者在评论中说他使用的是 MSVC++ 2010,doesn't support them。也就是说,如果您想添加它,它可能是一个有效且有用的答案。【参考方案2】:
一个模板只能有 一个 基本定义。如果您需要可变数量的参数并且不想像@awoodland 建议的那样使用“空类型”结构,并且如果您有 C++0x 编译器,那么您可以使用可变参数模板:
template <typename ...Dummy> struct foo; // base case, never instantiated!
template <typename T> struct foo<T> /*...*/ ; // partial spec. for one parameter
template <typename T, typename U> struct foo<T, U> /*...*/ ; // ditto for two
【讨论】:
【参考方案3】:这是未经测试的代码,我没有手边的 boost 版本,但不管怎样
#include "boost/tuple.h"
template <class T>
class Blah;
template <class T>
class Blah< boost::tuple<T> >
void operator()(T arg);
;
template <class T, class U>
class Blah< boost::tuple<T, U> >
void operator()(T arg1, U arg2);
;
等等。等等
【讨论】:
以上是关于通过模板参数号重载模板类的主要内容,如果未能解决你的问题,请参考以下文章