C++ 模板类,变长参数如何做?

DavidHsing 2012-04-03 07:34:35
碰到个问题,比如我写一个 C++ 模板类:


template<typename ... TT> class CXXX


我想达到的目的是:参数类型、个数不确定,
那么在这个模板类的构造函数中,我如何得知传递进来的参数?

比如,在程序中用

CXXX<RECT, ICONINFO> temp


来创建一个实例,怎样才能知道参数的类型和长度?
谢谢大家!

(问题能解决的话,分不够再加)
...全文
487 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
j8daxue 2012-04-11
  • 打赏
  • 举报
回复
LZ看看C++设计新思维的Typelist有没什么灵感
DavidHsing 2012-04-06
  • 打赏
  • 举报
回复
呵呵,谢谢大家!
不过按照目前 VS2010 的情况来看是不支持的,放弃了。
自己改变了一下思路,把变长模板类换成了常规类,采用模板函数形式。已变相解决问题。
只能说是这是目前 VS2010 的一个遗憾吧
unituniverse2 2012-04-06
  • 打赏
  • 举报
回复
这个需要编译器支持。C++11 ISO的内容
文档在这里:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2555.pdf
DavidHsing 2012-04-06
  • 打赏
  • 举报
回复
VS2010 的 tuple 没有变长模板,连搜索“...” 都没有

#include <tuple>
mngzilin 2012-04-06
  • 打赏
  • 举报
回复
我在一个模板中见过这种写法,虽然不是任意长度的参数,但是基本上这种方式是比较简单的


#define DELEGATE(TYPENAME_TEMPLATE_LIST,ARG_TYPE_LIST,ARG_PARAM_LIST,ARG_TYPE_PARAM_LIST) \
\
template<typename RET TYPENAME_TEMPLATE_LIST> \
class IFunction<RET(ARG_TYPE_LIST)> \
..........................
template<typename RET TYPENAME_TEMPLATE_LIST> \
class MyTest<RET(ARG_TYPE_LIST)> \
..........................


#define TYPENAME_TEMPLATE_LIST_0
#define TYPENAME_TEMPLATE_LIST_1 TYPENAME_TEMPLATE_LIST_0 ,typename TT1
#define TYPENAME_TEMPLATE_LIST_2 TYPENAME_TEMPLATE_LIST_1 ,typename TT2
#define TYPENAME_TEMPLATE_LIST_3 TYPENAME_TEMPLATE_LIST_2 ,typename TT3

#define ARG_TYPE_LIST_0
#define ARG_TYPE_LIST_1 TT1
#define ARG_TYPE_LIST_2 ARG_TYPE_LIST_1 ,TT2
#define ARG_TYPE_LIST_3 ARG_TYPE_LIST_2 ,TT3

#define ARG_PARAM_LIST_0
#define ARG_PARAM_LIST_1 at1
#define ARG_PARAM_LIST_2 ARG_PARAM_LIST_1 ,at2
#define ARG_PARAM_LIST_3 ARG_PARAM_LIST_2 ,at3

#define ARG_TYPE_PARAM_LIST_0
#define ARG_TYPE_PARAM_LIST_1 TT1 at1
#define ARG_TYPE_PARAM_LIST_2 ARG_TYPE_PARAM_LIST_1 ,TT2 at2
#define ARG_TYPE_PARAM_LIST_3 ARG_TYPE_PARAM_LIST_2 ,TT3 at3

DELEGATE(TYPENAME_TEMPLATE_LIST_0,ARG_TYPE_LIST_0,ARG_PARAM_LIST_0,ARG_TYPE_PARAM_LIST_0)
DELEGATE(TYPENAME_TEMPLATE_LIST_1,ARG_TYPE_LIST_1,ARG_PARAM_LIST_1,ARG_TYPE_PARAM_LIST_1)
DELEGATE(TYPENAME_TEMPLATE_LIST_2,ARG_TYPE_LIST_2,ARG_PARAM_LIST_2,ARG_TYPE_PARAM_LIST_2)
DELEGATE(TYPENAME_TEMPLATE_LIST_3,ARG_TYPE_LIST_3,ARG_PARAM_LIST_3,ARG_TYPE_PARAM_LIST_3)

#undef TYPENAME_TEMPLATE_LIST_0
#undef TYPENAME_TEMPLATE_LIST_1
#undef TYPENAME_TEMPLATE_LIST_2
#undef TYPENAME_TEMPLATE_LIST_3

#undef ARG_TYPE_LIST_0
#undef ARG_TYPE_LIST_1
#undef ARG_TYPE_LIST_2
#undef ARG_TYPE_LIST_3

#undef ARG_PARAM_LIST_0
#undef ARG_PARAM_LIST_1
#undef ARG_PARAM_LIST_2
#undef ARG_PARAM_LIST_3

#undef ARG_TYPE_PARAM_LIST_0
#undef ARG_TYPE_PARAM_LIST_1
#undef ARG_TYPE_PARAM_LIST_2
#undef ARG_TYPE_PARAM_LIST_3
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 的回复:]

VS2010 的 tuple 没有变长模板,连搜索“...” 都没有
C/C++ code

#include <tuple>
[/Quote]
这个不是采用变长模板实现的,使用默认模板参数实现的。

要在vs下使用变长模板的话可以参考这个来变相的变长模板。
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 的回复:]

维基百科说明

看来我用的 VS2010 是没戏了,除非等 vs 更新了
[/Quote]
VS2010也有tuple啊,看看tuple的实现。
redui 2012-04-05
  • 打赏
  • 举报
回复
VC肯定是可以变通解决的,具体还得看你的实际需求
DavidHsing 2012-04-05
  • 打赏
  • 举报
回复
维基百科说明

看来我用的 VS2010 是没戏了,除非等 vs 更新了
lanhxg 2012-04-04
  • 打赏
  • 举报
回复
先罗列所有的参数,然后从最后面开始指定默认值,这样就好了。要是还要不同顺序的,那就根据顺序做重载函数,
  • 打赏
  • 举报
回复
参考gcc tuple的实现方法

  template<std::size_t _Idx, typename... _Elements>
struct _Tuple_impl;

template<std::size_t _Idx>
struct _Tuple_impl<_Idx>
{
protected:
void _M_swap_impl(_Tuple_impl&) { /* no-op */ }
};

template<std::size_t _Idx, typename _Head, typename... _Tail>
struct _Tuple_impl<_Idx, _Head, _Tail...>
: public _Tuple_impl<_Idx + 1, _Tail...>,


  template<typename... _Elements> 
class tuple : public _Tuple_impl<0, _Elements...>


DavidHsing 2012-04-04
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 的回复:]
template<class A,class B> class CXXX
就可以传递2个参数。
[/Quote]

谢谢!不过答非所问
开水 2012-04-04
  • 打赏
  • 举报
回复
使用 va_start 和 va_end 宏,例如
/* va_start example */
#include <stdio.h>
#include <stdarg.h>

void PrintFloats ( int amount, ...)
{
int i;
double val;
printf ("Floats passed: ");
va_list vl;
va_start(vl,amount);
for (i=0;i<amount;i++)
{
val=va_arg(vl,double);
printf ("\t%.2f",val);
}
va_end(vl);
printf ("\n");
}

int main ()
{
PrintFloats (3,3.14159,2.71828,1.41421);
return 0;
}

参考:http://www.cplusplus.com/reference/clibrary/cstdarg/va_start/
hztj2005 2012-04-03
  • 打赏
  • 举报
回复
template<class A,class B> class CXXX
就可以传递2个参数。









DavidHsing 2012-04-03
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]
C++11直接支持模板参数
GCC 4.3 已经支持
[/Quote]

对的,以前称之为 C++0x。
只是我不知道怎么才能获取到我例子中的 typename ... TT 为 RECT, ICONINFO 。
有方法吗?
  • 打赏
  • 举报
回复
C++11直接支持模板参数
GCC 4.3 已经支持
hztj2005 2012-04-03
  • 打赏
  • 举报
回复
对于函数来说,变长就重载多个函数。
hztj2005 2012-04-03
  • 打赏
  • 举报
回复
印象中,c++不允许函数变长参数,
至于模板不了解。
西山小月 2012-04-03
  • 打赏
  • 举报
回复
可以把长度也放在参数里面传进去

15,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧