开发者

Optional method arguments in C++, but from the callee's side?

In C++ methods can have optional arguments, like this:

void myFunction (int arg1, int arg2=0);

In this case myFunction can be called with 1 integer or with two. If you omit the second integer, the value 0 is passed instead.

I am now looking for ways to obtain the same functionality, but from the callee's side. Suppose I have an interface I need to implment (e.g. an observer interface). At this moment it looks like this:

class IObserver
   {
   public:
      virtual bool operator() (OtherClass *instance) = 0;
   };

Until now, the code calling the observers only wanted to pass the instance argument. But, in order to implement 开发者_开发技巧some new functionality, I want to add some other arguments, like this:

class IObserver
   {
   public:
      virtual bool operator() (OtherClass *instance, int firstOptional, int secondOptional) = 0;
   };

But, given that these new arguments only makes sense for a small number of very specific observers, I don't want to add the additional arguments to the other 99% of the observers.

To make the situation more complex, the code to which you give the observer also accepts a lambda expression. So you could write something like this:

addObserver (observee, [](OtherClass *instance)->bool {/*do something here*/ return true;}

The simplicity of the original signature made it nice and easy to pass a lambda expression. With the additional arguments I am now forced to add these arguments to the lambda expressions even if they don't make sense for that observer.

I know the problem can be solved by introducing an additional adapter, but I what I'm actually looking for is a way to have real optional arguments from the callee's side.

Any suggestions on how to solve this in a clean but easy way?


If you don't want to implement overloads of the operator bool in every concrete class that implements the interface, then you can just let the interface provide non-virtual overloads that forward the calls to a single virtual member functions (with however many arguments) that must be implemented.

Yeah, it's a bit different from Java interfaces, which cannot provide that kind of functionality.

Another way it's good, is that if you want you can let the non-virtual forwarders do pre- and post-condition checking and/or argument validation, and you can set breakpoints there for debugging. :-)

Cheers & hth.,


In this case, I would consider abstract concept of additional parameters, since they are for only some specific implementations. Your interface will become like:

class IObserver 
   { 
   public: 
      virtual bool operator() (OtherClass *instance, IObserverArgs* args) = 0;
   }; 

And implementation need additional arguments can have their own IObserverArgs implementation. However, this may not be flexible enough towards lambda.


But you can overload operator() on the number and types of arguments. Why isn't this satisfactory?


You could consider the version of operator() with extra arguments just as another functionality of your concrete class.

Overload the operator() in the few concrete classes that need extra argument.

class Observer1
{
public:
   virtual bool operator() (OtherClass *instance);
   bool operator() (OtherClass *instance, int firstOptional, int secondOptional);
};
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜