我怎么能写一个函数,接受可变数量的参数?这可能吗?怎么可能?


当前回答

唯一的方法是使用C样式变量参数,如下所述。请注意,这不是一个推荐的实践,因为它不类型安全且容易出错。

其他回答

如果不使用C风格的可变参数(…),就没有标准的c++方法可以做到这一点。

当然,根据上下文,有一些默认参数“看起来”像可变数量的参数:

void myfunc( int i = 0, int j = 1, int k = 2 );

// other code...

myfunc();
myfunc( 2 );
myfunc( 2, 1 );
myfunc( 2, 1, 0 );

这四个函数调用都使用不同数量的参数调用myfunc。如果没有给出参数,则使用默认参数。但是请注意,只能省略尾随参数。没有办法,例如省略i而只给出j。

你可能不应该这样做,你可以用一种更安全、更简单的方式做你想做的事情。从技术上讲,要在C语言中使用可变数量的参数,需要包含stdarg.h。由此,您将获得va_list类型以及对其进行操作的三个函数va_start()、va_arg()和va_end()。

#include<stdarg.h>

int maxof(int n_args, ...)
{
    va_list ap;
    va_start(ap, n_args);
    int max = va_arg(ap, int);
    for(int i = 2; i <= n_args; i++) {
        int a = va_arg(ap, int);
        if(a > max) max = a;
    }
    va_end(ap);
    return max;
}

要我说,这真是一团糟。它看起来很糟糕,不安全,而且充满了与你在概念上试图实现的目标无关的技术细节。相反,可以考虑使用重载或继承/多态性、构建器模式(如流中的操作符<<())或默认参数等。这些都是更安全的:编译器会更多地了解你要做什么,这样就有更多的机会在你断腿之前阻止你。

除了可变参数或重载,你可以考虑将参数聚合在std::vector或其他容器中(例如std::map)。就像这样:

template <typename T> void f(std::vector<T> const&);
std::vector<int> my_args;
my_args.push_back(1);
my_args.push_back(2);
f(my_args);

通过这种方式,您将获得类型安全,并且这些可变参数的逻辑含义将是显而易见的。

当然,这种方法可能会有性能问题,但您不必担心,除非您确定无法为此付出代价。它是c++的一种“Pythonic”方法…

在c++11中,你可以做:

void foo(const std::list<std::string> & myArguments) {
   //do whatever you want, with all the convenience of lists
}

foo({"arg1","arg2"});

列表初始化项FTW!

正如其他人所说,c风格的变量。但是你也可以对默认参数做类似的事情。