传递具有不同类型的可变数量的参数 - C ++

时间:2010-08-24 10:41:51

标签: c++

我使用C ++进行编码,并对省略号有几个问题:

  1. 是否可以将类或类指针传入省略号?

  2. 基本上我想做的是传递char*class类型的可变数量的参数。我目前正在使用省略号并试图弄清楚如何传入课堂。如果省略号不适用于此处,有哪些选项?

  3. 我想让用户使用func( params 1, params2, ...)直接调用函数,而不是先将参数传递给向量或数组,然后再将向量或数组作为参数传递给函数。

6 个答案:

答案 0 :(得分:18)

您应该考虑使用可变参数函数(C风格)是一个危险的缺陷。 如果传递给函数的对象与等待的类型不匹配,或者如果你没有输入确切的参数数量,那么你基本上在运行时发生了剧烈的崩溃

在Bjarne Stroustrup C ++深度系列 - C ++编码标准 - 101规则,指南和最佳实践Herb Sutter和Andrei Alexandrescu,第98章:不要使用varargs(省略号)

我非常赞同@ tenfour的提议:

  • 使用包含所有参数的std::vector

答案 1 :(得分:10)

你可以将你想要的任何东西传递给可变参数函数,但这对你编写方便的函数没有帮助,因为你丢失了参数的类型信息。

根据您想要实现的目标,有更好的选择:

  • 链接<<()等运营商:

    helper() << a << b << c;
    helper(a)(b)(c);
    
  • 使用(伪)可变参数模板:

    template<class T0>           void func(T0 t0)        { ... }
    template<class T0, class T1> void func(T0 t0, T1 t1) { ... }
    // ...
    
    // or if you can use C++0x features:
    template<class... Args> void func(Args... args) { ... }
    
  • ...更多?

答案 2 :(得分:4)

你可以用varargs传递一个类指针,是的。但是接收指针的函数需要知道如何处理它。它必须将其转换为可用的东西。这就是printf()让你在格式说明符中指定参数类型的原因。

另一种方法是将列表传递给函数,例如std::vector

[edit]你可能想要做一些事情来缩短语法,所以你可以传递你的参数,如:

foo(blah, StartAList(a)(b)(c)(d));

或stream-ish:

foo(blah) >> a >> b >> c >> d;

或通过重载:

void foo(T a) { ... }
void foo(T a, T b) { ... }
void foo(T a, T b, T c) { ... }

答案 3 :(得分:3)

使用C ++ 0x可变参数模板,您可以将所有参数打包到元组中,并使用我在下面的线程中发布的代码将它们解压缩到函数调用(静态函数或对象函数)。

How do I expand a tuple into variadic template function's arguments?

答案 4 :(得分:1)

使用C ++ 0x

中新引入的特征变量模板参数,可以使用真正的类型安全变量参数函数

你也可以使用boost :: any

答案 5 :(得分:0)

如果始终使用类实例(或指针),最好使用固定参数,该参数在变量参数列表之前传递,如printf中的格式。关于...参数,它们可以具有任何类型(包括类实例或指针),并且它们的数量和类型取决于调用者和被调用函数之间的某些约定。例如,对于printf,此类约定由格式字符串定义。您需要定义这样的“通信协议”,它允许使用变量参数列表。当然,这不安全。