我有一个Visual Studio 2008 C ++ DLL,我想接受可变数量的参数并知道每个参数的类型。例如:
__declspec( dllexport ) void Foo( const char* object, const char* function, ... )
{
printf( "%s::%s( ", object, function );
va_list list;
va_start( list, function );
while( va_arg( list, ??? ) )
{
printf( "[%s] %s ", type, value );
}
va_end( list );
printf( " )\r\n" );
}
预期用法是这样的:
Buzz api;
int a = 1;
api.DoSomething( a, "hello", 0.2f );
Foo( "Buzz", "DoSomething", a, "hello", 0.2f );
预期输出如下所示:
Buzz::DoSomething( [int] 1, [const char*] "hello", [float] 0.2 )
这可能是RTTI的可能吗?如果无法使用可变参数解决方案(并且我怀疑它不是),我可以使用包含多个1-n参数重载的解决方案。
谢谢, PaulH
答案 0 :(得分:1)
首先:C ++支持“C”样式的可变参数函数,以便与C代码仅兼容。不建议您在新的C ++代码中使用它们,因为它们不能强制实现类型安全。
可变参数函数将所有“...”参数作为无类型值传递给堆栈。作为参数传递的值的类型必须由你(作为作者)的逻辑推导出来该功能)放入你写的功能。也就是说,告诉printf参数类型(格式字符串后面的参数)的唯一内容就是格式字符串本身。
这在C ++中与在C中一样.RTTI无法为堆栈上的任意值提供任何类型信息。
如果值是类层次结构中对象(相关类的实例)的所有指针,那么您可以使用dynamic_cast来确定类型......但是您必须编写代码来自己处理不同的类,语言不适合你。
答案 1 :(得分:0)
一个可变参数解决方案是可能的,但不是C方式而不是当前版本的语言。如果你的编译器实现了可变参数模板,你可以用它们来实现。您可以通过使用具有长列表默认参数的函数,将当前版本的可变参数模板模拟为任意最大值(如果使用预处理器魔法,则由变量设置)。
因此,根据您想要的方式,您需要学习可变参数模板和/或预处理器。一旦你做了必要的研究,前者将变得明显。后者有点难度,但是如果你看看src到boost :: function这样的事情就会变得很明显。