开发者

Passing Variable Number of Arguments with different type - C++

I am coding in C++ and have a few questions regarding the ellipsis:

  1. Is it possib开发者_运维知识库le to pass in class or class pointer into the ellipsis?

  2. Basically what I want to do is to pass in variable number of arguments in the type of char* and class. I am using ellipsis currently and trying to figure out how to pass in the class. If ellipsis isn't applicable over here, what are the options available?

I want to let the user to directly call the function using func( params 1, params2, ...) without explicitly assigning the params into a vector or array first before passing the vector or array as argument to the function.


You should consider that using variadic functions (C-style) is a dangerous flaw. If the objects passed to the function mismatch the type awaited, or if you don't put the exact number of parameters awaited, then you basically have a violent crash at runtime.

In Bjarne Stroustrup C++ In Depth Series - C++ Coding Standards - 101 Rules, Guidelines, And Best Practices by Herb Sutter and Andrei Alexandrescu, chapter 98: Don't use varargs (ellipsis)

I deeply subscribe to @tenfour's proposal:

  • use an std::vector that contains all your parameters.


You can pass whatever you want to variadic functions, but this won't help you in writing convenient functions as you are losing the type information for the arguments.

Depending on what you want to achieve there are better alternatives:

  • chaining operators like << or ():

    helper() << a << b << c;
    helper(a)(b)(c);
    
  • using (pseudo-)variadic templates:

    template<class T0>           void func(T0 t0)        { ... }
    template<class T0, class T1> void func(T0 t0, T1 t1) { ... }
    // ...
    
    // or if you can use C++0x features:
    template<class... Args> void func(Args... args) { ... }
    
  • ... more?


You can pass a class pointer with varargs, yes. But the function receiving the pointer needs to know what to do with it. It will have to cast it to something usable. This is why printf() makes you specify the argument type in the format specifier.

One alternative is to pass a list to the function, like std::vector.

[edit] You might be want to do something to make the syntax shorter, so you can pass in your arguments like:

foo(blah, StartAList(a)(b)(c)(d));

or stream-ish:

foo(blah) >> a >> b >> c >> d;

or by overloading:

void foo(T a) { ... }
void foo(T a, T b) { ... }
void foo(T a, T b, T c) { ... }


Using C++0x variadic templates, you can pack all your arguments into a tuple and use the code I posted in the thread below to unpack them into a function call (static function or object function).

How do I expand a tuple into variadic template function's arguments?


True typesafe variable argument functions are possible with the newly introduced feature variable template arguments in C++0x

You can also get by using boost::any


If class instance (or pointer) is used always, it is better to use fixed parameter, which is passed before variable parameters list, like format in printf. Regarding ... parameters, they may have any type (including class instance or pointer), and their amount and types depend on some convention between a caller and called function. For example, for printf, such convention is defined by format string. You need to define such "communication protocol", which allows to use variable arguments list. Of course, this is not safe.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜