Skip some arguments in a C++ function?

前端 未结 4 582
自闭症患者
自闭症患者 2020-12-01 21:37

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 t

相关标签:
4条回答
  • 2020-12-01 21:54

    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.

    0 讨论(0)
  • 2020-12-01 22:01

    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;
    }
    
    0 讨论(0)
  • 2020-12-01 22:12

    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.

    0 讨论(0)
  • 2020-12-01 22:17

    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

    0 讨论(0)
提交回复
热议问题