C++ 不定参数的类型问题

shihyuyao 2013-04-27 11:05:30
要实现一个函数,参数个数未知,类型未知,通常来说使用不定参数了。但用不定参数可以知道参数的类型吗? 我想根据类型来决定不同的实现。 如:

void func(int a, ...)
{
...
for(.....)
{
xx = 取下一个参数
switch(参数的类型)
{
case 整型: doInt(xx); break;
case 字符串: doString(xx); break;
...
}
}
}

类似的功能如何实现??
...全文
777 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
u010458922 2013-05-01
  • 打赏
  • 举报
回复
如果您的编译器支持C++11新便准,用Variadic Templates应该很简单。下面是一个具体的例子: #include <iostream> using std::cout; template <typename T> void g(T x) { cout << x << " "; } void f() { } // do nothing template <typename T, typename... Tail> void f(T head, Tail... tail) { g(head); // do someting to head f(tail...); // tr y again with tail } int main() { cout << "first: "; f(1,2.2,"hello"); cout << "\nsecond: "; f(0.2,'c',"yuck!",0,1,2); cout << "\n"; }
rocktyt 2013-04-30
  • 打赏
  • 举报
回复
引用 20 楼 Athenacle_ 的回复:
引用 12 楼 rocktyt2 的回复:
[quote=引用 11 楼 Athenacle_ 的回复:] [quote=引用 7 楼 rocktyt2 的回复:] [quote=引用 6 楼 zhcosin 的回复:] 对于 C++ 来说,你有这样的需求通常意味着的你解决问题的思路有问题,把你的原始问题也就是你想用这样的函数来解决的问题拿出来,肯定有 C++ 的方式来解决它。
比如我想写一个类型安全的printf之类的?
C++从C中继承过来的变参函数本身就不可能是类型安全的。因为从函数原型里面推断不出来参数的类型、数目,编译器就不可能做类型检查[/quote]我没有说要用c里面继承过来的变参函数,我在说,实际上是会有需要用变参函数的场合,并且举了例子,而实现可以用c++11里追加的变参模板,只不过上面没提到而已[/quote] 没看过c++11,不敢乱说话。。如果真是可变参数模板,那结合typeinfo应该可以实现类型安全[/quote]用模板就不需要typeinfo了,类型都在编译器确定的,typeinfo主要还是在多态类型判断的时候用 我自己尝试着写过一个类型安全的printf不,过因为格式字符串没法在编译器确定,最后只能采用抛异常的方式来通知类型转换失败 如果所有参数都是编译器常量倒是用了一大堆constexpr在编译器报错了。。。
zhcosin 2013-04-28
  • 打赏
  • 举报
回复
引用 7 楼 rocktyt2 的回复:
引用 6 楼 zhcosin 的回复:
对于 C++ 来说,你有这样的需求通常意味着的你解决问题的思路有问题,把你的原始问题也就是你想用这样的函数来解决的问题拿出来,肯定有 C++ 的方式来解决它。
比如我想写一个类型安全的printf之类的?
类型安全的输出 C++ 提供的方式实在太方便了,使用输入输出流不是方便得很吗,干嘛非要用 printf ?
赵4老师 2013-04-28
  • 打赏
  • 举报
回复
参考VARIANT的定义。
rocktyt 2013-04-28
  • 打赏
  • 举报
回复
引用 6 楼 zhcosin 的回复:
对于 C++ 来说,你有这样的需求通常意味着的你解决问题的思路有问题,把你的原始问题也就是你想用这样的函数来解决的问题拿出来,肯定有 C++ 的方式来解决它。
比如我想写一个类型安全的printf之类的?
zhcosin 2013-04-28
  • 打赏
  • 举报
回复
对于 C++ 来说,你有这样的需求通常意味着的你解决问题的思路有问题,把你的原始问题也就是你想用这样的函数来解决的问题拿出来,肯定有 C++ 的方式来解决它。
就是那个党伟 2013-04-28
  • 打赏
  • 举报
回复
3楼+1 不定长模版
漫步者、 2013-04-28
  • 打赏
  • 举报
回复
这个采用模板吧,可以参考typeinfo头文件看看
Athenacle_ 2013-04-28
  • 打赏
  • 举报
回复
引用 12 楼 rocktyt2 的回复:
引用 11 楼 Athenacle_ 的回复:
[quote=引用 7 楼 rocktyt2 的回复:] [quote=引用 6 楼 zhcosin 的回复:] 对于 C++ 来说,你有这样的需求通常意味着的你解决问题的思路有问题,把你的原始问题也就是你想用这样的函数来解决的问题拿出来,肯定有 C++ 的方式来解决它。
比如我想写一个类型安全的printf之类的?
C++从C中继承过来的变参函数本身就不可能是类型安全的。因为从函数原型里面推断不出来参数的类型、数目,编译器就不可能做类型检查[/quote]我没有说要用c里面继承过来的变参函数,我在说,实际上是会有需要用变参函数的场合,并且举了例子,而实现可以用c++11里追加的变参模板,只不过上面没提到而已[/quote] 没看过c++11,不敢乱说话。。如果真是可变参数模板,那结合typeinfo应该可以实现类型安全
rocktyt 2013-04-28
  • 打赏
  • 举报
回复
引用 17 楼 zhcosin 的回复:
引用 10 楼 rocktyt2 的回复:
[quote=引用 9 楼 zhcosin 的回复:] [quote=引用 7 楼 rocktyt2 的回复:] [quote=引用 6 楼 zhcosin 的回复:] 对于 C++ 来说,你有这样的需求通常意味着的你解决问题的思路有问题,把你的原始问题也就是你想用这样的函数来解决的问题拿出来,肯定有 C++ 的方式来解决它。
比如我想写一个类型安全的printf之类的?
类型安全的输出 C++ 提供的方式实在太方便了,使用输入输出流不是方便得很吗,干嘛非要用 printf ?[/quote]sscanf很好用,不用不承认,想限定格式输入用c++的流太麻烦了,而且难看懂,输出稍微好点[/quote] 你看清楚,人家要求类型安全,sscanf 类型安全吗?[/quote]怎么那么没逻辑的,我在说的是这种需求是存在的,不要一棍子打死
qiminixi 2013-04-28
  • 打赏
  • 举报
回复
可以参考printf和scanf的实现,他们都是参数可变函数。 第一个参数是一个字符串,该字符串指明有多少个参数,以及它们各自是什么类型: printf("%d%c",n,c);
zhcosin 2013-04-28
  • 打赏
  • 举报
回复
引用 10 楼 rocktyt2 的回复:
引用 9 楼 zhcosin 的回复:
[quote=引用 7 楼 rocktyt2 的回复:] [quote=引用 6 楼 zhcosin 的回复:] 对于 C++ 来说,你有这样的需求通常意味着的你解决问题的思路有问题,把你的原始问题也就是你想用这样的函数来解决的问题拿出来,肯定有 C++ 的方式来解决它。
比如我想写一个类型安全的printf之类的?
类型安全的输出 C++ 提供的方式实在太方便了,使用输入输出流不是方便得很吗,干嘛非要用 printf ?[/quote]sscanf很好用,不用不承认,想限定格式输入用c++的流太麻烦了,而且难看懂,输出稍微好点[/quote] 你看清楚,人家要求类型安全,sscanf 类型安全吗?
铁文 2013-04-28
  • 打赏
  • 举报
回复
如果每办法使用C++不定长模板(比如编译器不支持,又或者参数个数只能在运行时决定),可以用老办法,下面的代码来自MSDN:
#include <stdio.h>
#include <stdarg.h>

void testit ( int i, ...)
{
   va_list argptr;
   va_start(argptr, i);

   if ( i == 0 ) {
      int n = va_arg( argptr, int );
      printf( "%d\n", n );
   } else {
      char *s = va_arg( argptr, char* );
      printf( "%s\n", s);
   }
}

int main()
{
   testit( 0, 0xFFFFFFFF ); // 1st problem: 0xffffffff is not an int
   testit( 1, NULL );       // 2nd problem: NULL is not a char*
}
Athenacle_ 2013-04-28
  • 打赏
  • 举报
回复
引用 2 楼 qq120848369 的回复:
自己制定一下fmt作为第一个参数, 解析fmt以便了解函数的参数栈上都是什么类型的变量.
+1 就像printf的格式字符串
aj3423 2013-04-28
  • 打赏
  • 举报
回复
c++11 不定长模板+ do_xxx函数重载
#include <string>
#include <iostream>
using namespace std;

void do_job(int x) {
	cout << "do_job(int " << x << ")" << endl;
}
void do_job(float x) {
	cout << "do_job(float " << x << ")" << endl;
}
void do_job(string x) {
	cout << "do_job(string " << x << ")" << endl;
}

void func() {
	cout << "func(empty), recursion finished" << endl;
}
template<typename first_t, typename...rest_t>
void func(first_t first, rest_t... rest) {
	do_job(first);
	func(rest...);
}


int main() {
	string a="a"; int b=10; float c=20.0;

	func(a,b,c);
}

输出: http://ideone.com/t0r5Hj
一叶之舟 2013-04-28
  • 打赏
  • 举报
回复
用模板就可以了,或用void*,加上类型就可以了,好多人不推荐用。但用好了一样的效果。
qj5656 2013-04-28
  • 打赏
  • 举报
回复
用可变长参数。。。。。
ri_aje 2013-04-28
  • 打赏
  • 举报
回复

template <typename T, typename ... Ts>
void func(T t, Ts ... ts)
{
    ...
}
rocktyt 2013-04-28
  • 打赏
  • 举报
回复
引用 11 楼 Athenacle_ 的回复:
引用 7 楼 rocktyt2 的回复:
[quote=引用 6 楼 zhcosin 的回复:] 对于 C++ 来说,你有这样的需求通常意味着的你解决问题的思路有问题,把你的原始问题也就是你想用这样的函数来解决的问题拿出来,肯定有 C++ 的方式来解决它。
比如我想写一个类型安全的printf之类的?
C++从C中继承过来的变参函数本身就不可能是类型安全的。因为从函数原型里面推断不出来参数的类型、数目,编译器就不可能做类型检查[/quote]我没有说要用c里面继承过来的变参函数,我在说,实际上是会有需要用变参函数的场合,并且举了例子,而实现可以用c++11里追加的变参模板,只不过上面没提到而已
Athenacle_ 2013-04-28
  • 打赏
  • 举报
回复
引用 7 楼 rocktyt2 的回复:
引用 6 楼 zhcosin 的回复:
对于 C++ 来说,你有这样的需求通常意味着的你解决问题的思路有问题,把你的原始问题也就是你想用这样的函数来解决的问题拿出来,肯定有 C++ 的方式来解决它。
比如我想写一个类型安全的printf之类的?
C++从C中继承过来的变参函数本身就不可能是类型安全的。因为从函数原型里面推断不出来参数的类型、数目,编译器就不可能做类型检查
加载更多回复(3)

64,281

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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