Skip some arguments in a C++ function?

核能气质少年 提交于 2019-12-17 16:44:17

问题


I have a C++ function that has 5 arguments, all of which have default values. If I pass in the first three arguments, the program will assign a default value to the last two arguments. Is there any way to pass 3 arguments, and skip one in the middle, giving values to say, the first, second, and fifth arguments?


回答1:


Not directly, but you might be able to do something with 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);

The downside is of course that you are re-specifying the default parameters. I'm sure somebody else will come along with a more clever solution, but this could work if you're really desperate.




回答2:


With a classical 5 arguments function, there is no way to give it only 3 or 4. You can only write 3 or 4 with default arguments but at the end you will get a function call with 5 arguments.

There are also issues with you system if there are several parameters with the same type. For instance, if you have foo(int a=4,int b=5) and call foo(10), how do you know you want to call foo(10,5) or foo(4,10) ?

With C++11 tuples and Named parameters idiom, you can cheat it a little bit.

#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
}

An alternative method is to use std::bind as described there




回答3:


No, It is not possible.
However I would suggest you should use parameters' datatype array instead to achieve the scenario you gave. You can overload as well. If the datatypes of parameters varies then you should define a class which has required parameters as members. Pass the object of that class. It will not only solve your problem but also it is recommended from the perspective of maintainability as well.




回答4:


Probably this is something that you may be looking for, just a workaround !

/*
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;
}

The following is another workaround may be this helps too !

/*
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;
}


来源:https://stackoverflow.com/questions/19024188/skip-some-arguments-in-a-c-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!