15

我有一个 C++ 函数,它有 5 个参数,所有参数都有默认值。如果我传入前三个参数,程序将为最后两个参数分配一个默认值。有没有办法传递 3 个参数,并在中间跳过一个,给出第一个、第二个和第五个参数的值?

4

4 回答 4

6

不是直接的,但你可以用 std::bind 做一些事情:

int func(int arg1 = 0, int arg2 = 0, int arg3 = 0);

// elsewhere...
using std::bind;
using std::placeholders::_1;
auto f = bind(func, 0, _1, 0);

int result = f(3); // Call func(0, 3, 0);

缺点当然是您要重新指定默认参数。我相信其他人会提出一个更聪明的解决方案,但如果你真的很绝望,这可能会奏效。

于 2013-09-26T13:03:00.780 回答
2

对于经典的 5 参数函数,没有办法只给它 3 或 4。你只能用默认参数编写 3 或 4,但最后你会得到一个带有 5 个参数的函数调用。

如果有多个相同类型的参数,您的系统也会出现问题。例如,如果你有foo(int a=4,int b=5)并且调用foo(10),你怎么知道你想调用foo(10,5)or foo(4,10)

使用 C++11 元组和命名参数 idiom,您可以稍微欺骗一下。

#include <iostream>
#include <functional>
#include <tuple>
#include <string>

struct f_
{
    private:

    typedef std::tuple<int,int,double> Args;

    //default arguments
    static constexpr const Args defaults = std::make_tuple(10,52,0.5);
    Args args;
    public :
    f_():args(defaults)
    {}

    template <int n,class T> f_& setArg(T&& t)
    {
        std::get<n>(args) = t;
        return *this;
    }

    void operator()() 
    {
        return (*this)(std::move(args));
    }

    void operator()(Args&& a)
    {
        int n1=std::get<0>(a);
        int n2=std::get<1>(a);
        double n3=std::get<2>(a);

        std::cout<<n1<<" "<<n2<<" "<<n3<<std::endl;
    }
};
#define set(n,v) setArg<n>((v))
int main()
{
    //f_().set<1>(42).set<3>("foo") ();
    f_().setArg<1>(42)(); //without Macro
    f_().set(0,666).set(1,42)(); //with Macro
    f_()(); //without any parameters
    f_()(std::forward_as_tuple(-21,-100,3.14)); //direct call
}

另一种方法是使用那里描述的 std::bind

于 2013-09-26T13:18:22.670 回答
0

不,这是不可能的。
但是我建议你应该使用参数的数据类型数组来实现你给出的场景。你也可以超载。如果参数的数据类型不同,那么您应该定义一个具有所需参数作为成员的类。传递该类的对象。它不仅可以解决您的问题,而且从可维护性的角度也值得推荐。

于 2013-09-26T09:26:24.617 回答
-2

可能这是您可能正在寻找的东西,只是一种解决方法!

/*
Function f() is called by passing 2 arguments. So to make sure that these 2 arguments are treated as
first and third, whereas the second and the fourth are taken as defaults:

SOLUTION 1 : using recursive call
*/

#include <iostream>
using namespace std;


void f( int = 10,int = 20, int = 30, int = 40);

static int tempb;

static int flag = 1;

int main()
{
    cout << "calling function \n";
    //f();
    f(12,39);
}

void f( int a,int b,int c,int d )
{
    //static int flag = 1;
    //f();  
    if( flag == 1 )
    {
        --flag; 
        f();        //recursive call to intialize the variables a,b,c,d as per the prototype
        c = b;
        b = tempb;
        //cout << c;
    }
    else
    {
        tempb = b;
        return;
    }

    cout << endl <<"a = " << a  << endl << "b = "<< b << endl << "c = " << c << endl << "d = " << d << endl;
}

以下是另一种解决方法,可能也有帮助!

/*
Function f() is called by passing 2 arguments. So to make sure that these 2 arguments are treated as
first and third, whereas the second and the fourth are taken as defaults:

SOLUTION 2 : using static variable

*/

#include <iostream>
using namespace std;


void f( int = 10,int = 20, int = 30, int = 40);

static int tempb;

int main()
{
    f();
    f(12,39);
}

void f( int a,int b,int c,int d)
{
    static int flag = 1;

    if( flag == 1 )
    {
        --flag; 
        tempb = b;
        return;
    }
    else
    {
        c = b;
        b = tempb;
    }

    cout << "a = " << a << endl << "b = " << b << endl << "c = " << c << endl << "d = " << d;
}
于 2017-01-05T03:31:02.217 回答