【问题标题】:Skip some arguments in a C++ function?跳过 C++ 函数中的一些参数?
【发布时间】:2013-10-02 04:22:47
【问题描述】:

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

【问题讨论】:

  • 简答:否。
  • 有一些变通方法。但如果可以,请改为重载。

标签: c++ optimization arguments default-arguments


【解决方案1】:

不是直接的,但你可以用 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);

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

【讨论】:

    【解决方案2】:

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

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

    使用 C++11 元组和Named parameters 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
    }
    

    另一种方法是使用 there 所述的 std::bind

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

        • 我无法使用全局静态变量来选择方法参数。没有人应该使用这种方法。
        猜你喜欢
        • 2019-08-04
        • 2011-07-20
        • 2021-12-23
        • 2015-12-07
        • 2019-05-24
        • 2020-12-24
        • 2018-06-13
        • 1970-01-01
        相关资源
        最近更新 更多