C ++可变数量的参数

时间:2011-04-27 15:57:16

标签: c++

我需要定义一个可以接受可变数量参数的虚函数,问题是c样式省略号对非pod类型不起作用,我的内存量有限(2KB)所以我试图避免分配临时对象传递给函数,所有参数都是相同的类型(自定义共享指针),我也没有访问stl或boost。有没有一个c ++技巧可以让我用变量参数调用一个func?

5 个答案:

答案 0 :(得分:4)

假设您的参数类型属于Arg类,您可以尝试:

class ArgUser {
public:
    // syntactic sugar:
    void method() { // nullary
        doMethod();
    }
    void method( const Arg & a1 ) { // unary
        doMethod( &a1 );
    }
    void method( const Arg & a1, const Arg & a2 ) { // binary
        doMethod( &a1, &a2 );
    }
    // and so on, until max arity
private:
    // actual virtual function:
    virtual void doMethod( const Arg * a1=0, const Arg * a2=0 /*etc, until max arity */ ) = 0;
};

此解决方案具有以下属性:

  1. 它使用NVI idiom
  2. 它使用指针,因为即使对于未使用的默认参数,它们也不会导致创建临时值。
  3. 它将丑陋的指针封装在(内联)包装器方法中。
  4. 另一种解决方案(可能会或可能不会更有效)是:

    class AltArgUser {
    public:
        // syntactic sugar:
        void method() { // nullary
            doMethod( 0, 0 );
        }
        void method( const Arg & a1 ) { // unary
            doMethod( &&a1, 1 );
        }
        void method( const Arg & a1, const Arg & a2 ) { // binary
            const Arg * args[] = { &a1, &a2 };
            doMethod( args, 2 );
        }
        // and so on, until max arity
    private:
        // actual virtual function:
        virtual void doMethod( const Arg * args[], size_t numArgs ) = 0;
    };
    

    要决定使用哪一个,您需要研究为特定平台上的每个方法生成的汇编程序。无论你选择什么,你都应该保留包装函数。

答案 1 :(得分:2)

定义函数以获取指向参数数组的指针和数组大小的参数。

此外,如果您不想对固定大小的数组进行硬编码,则可以使用alloca在堆栈上分配存储,而不必担心跳转到堆或调用free。< / p>

答案 2 :(得分:1)

指向共享指针的指针是POD,您是否可以更改原型以使用每个参数的内存位置?像这样(未经测试):

shared_ptr arg1;
shared_ptr arg2;

ClassWithVirtualFunction c;

c.yourVirtualFunction(&arg1, &arg2, NULL);

ClassWithVirtualFunction
{
    virtual void yourVirtualFunction(shared_ptr* first, ...)
    {
        va_list marker;

        va_start( marker, first );

        shared_ptr* current=first;

        while (current != NULL)
        {
            /* do stuff with *current */
            current = va_arg( marker, shared_ptr* );
        }
        va_end(marker);
    }
}

答案 3 :(得分:0)

您可以使用实际上更快的固定数组,并且比可变数量的参数占用更少的空间。因为可变数量的参数可以进行大量检查和安全。

mytype arr[3];
arr[0] = a;
// etc
myfunction(arr, 3);

答案 4 :(得分:0)

也许如果你已经拥有自己的自定义指针类型,你可以定义自己的基本链表类(毕竟这是C ++),最后一个“指向下一个指针”为NULL表示变量数字的结尾ARGS。

这样的事情:

class MyPointer
{
  // Whatever you have/want
};

class MyArgs
{
  static int nargs; // Static class variable for total number of args
  MyPointer* data;
  MyArgs*    next; 

  public:
  MyArgs(int nargs)
  {  
    // Some funky constructor to create required number of args...
  }  

  MyPointer* operator[](int at)
  {  
    // Nice overloaded operator for you to get at data
  }  

};

class PlanToDoStuff
{
  public:
  virtual void foobar(MyArgs)=0;
};

class ActuallyDoStuff: public PlanToDoStuff
{
  public:
  void foobar(MyArgs)
  {  
    // Do stuff with args...
  }  
};

int main()
{
    MyArgs args(3);
    ActuallyDoStuff dosomething;
    dosomething.foobar(args);

}