8

Assume I have an interface

class I{
public:
    virtual void f(int id)=0;
    virtual void g(int id, float x)=0;
}

I need a proxy class, to do some sort of id to pointer mapping

class Proxy : I
{
    I * i[5];
public:
    void f(int id)
    {
        i[id]->f(id);
    }

    void g(int id, float x)
    {
        i[id]->g(id, x);
    }

}

So when i write

Proxy *p;
p->f(1);

f is called on the object with id=1

there are several such cases and interfaces are rather large. So I don't want to code all the functions in the proxy class. Is there way to do it automatically? maybe using macros, templates, overloading "->" etc.

4

3 回答 3

7

The easy solution is to define an operator-> that returns the pointer to the interface. But this will break your encapsulation since everybody can access your objects directly and you actually don't need your proxy class (you might as well just use a std::map).

Alternative you could do something like

template <typename Interface>
class Proxy
{
   Interface* interfaces[5];
public:
  template <typename F, typename... Params>
  auto operator()(F f, const int id,  Params... parameters)
           -> decltype((interfaces[id]->*f)(id, parameters...))
  { return (interfaces[id]->*f)(id, parameters...); }
};

It heavily relies on C++11 features so it might not compile with your compiler.

First it uses the Variadic templates. See https://en.wikipedia.org/wiki/Variadic_Templates for more information.

Next it uses decl_type. See https://en.wikipedia.org/wiki/Decltype for more information.

You have to use it like this:

  Proxy<I> p;
  ...

  p(&I::f,1);
  p(&I::g,3, 1.);
于 2012-04-20T13:04:39.633 回答
0

I don't know if this is suitable for you, but you could take care of this using pointers to functions...

ie.

#include <stdio.h>

typedef void (*f)(int);

void f1(int a)
{
    printf("f1: %d\n", a);
}
void f2(int a)
{
    printf("f2: %d\n", a);
}
int main(int argc, char *argv[])
{
    f array[5] = {NULL}; // create array of pointers
    array[0] = f1; // assign different functions on them
    array[1] = f2; // -||-

    array[0](10); // call them
    array[1](12);

    // and you end up with something like "array[i]();" in your proxy class...
}
于 2012-04-20T12:00:06.883 回答
0

Yet another solution.

http://coliru.stacked-crooked.com/a/857329ab4433a3a9

  #include <iostream>

  template <class F, class... Args>
  inline decltype(auto) invoke(F&& f, Args&&... args) 
     //-> decltype(std::forward<F>(f)(std::forward<Args>(args)...)
  { 
    return std::forward<F>(f)(std::forward<Args>(args)...);
  }

  int main()
  {
     using namespace std;

     cout<<"hello"<<endl;

     struct RaiiProxy {
        RaiiProxy(){
           cout<<"RaiiProxy in"<<endl;
        }
        ~RaiiProxy(){
           cout<<"RaiiProxy out"<<endl;
        }
     };
     auto proxy = [](auto&&f,auto&&...args){
        RaiiProxy raii;
        return invoke( forward<decltype(f)>(f), std::forward(args)... );
     };

     // Use as function
     proxy( [](){ cout<<"I am in proxy."<<endl; } );

     // Use raii
     {  RaiiProxy raii;
        cout<<"I am in RaiiProxy."<<endl;
     }

     cout<<"bye."<<endl;
  }
于 2018-07-08T07:28:30.850 回答