lundi 27 juin 2016

adapter class for C++ interface with move constructor


I am trying to write an adapter class for an interface class that accepts a) an implementation of the interface, which should be stack-allocated (so no new/delete handling should be required from the outside, the adapter itself may use new/delete) and b) a lambda function that will be called by a respective implementation of the interface.

#include <iostream>
#include <functional>

struct interface {
  virtual int hello() = 0;
};

struct implementation : public interface {
  virtual int hello() {
    std::cout << "hello()n";
    return 42;
  }
};

struct adapter {
  interface* obj;

  adapter(std::function<int()>&& func) {
    struct lambda : public interface {
      std::function<int()> func;
      lambda(std::function<int()> func_): func(func_) { }
      virtual int hello() {
        return this->func();
      }
    };
    this->obj = new lambda{func};
  }

  adapter(interface&& impl) {
    // TODO: pretty sure that's incorrect
    //       but can I somehow create a copy of "impl" on the heap?
    this->obj = &impl;
  }
};

int main() {
  adapter a([]() { std::cout << "hello from lambdan"; return 99; });
  a.obj->hello();

#if 0
  // ERROR
  adapter b(implementation());
  b.obj->hello();
#endif
  return 0;
}

This is the error I get when enabling the adapter b part.

prog.cpp: In function 'int main()':
prog.cpp:39:4: error: request for member 'obj' in 'b', which is of non-class type 'adapter(implementation (*)())'
  b.obj->hello();
    ^
  1. I don't understand the error at all, I would much appreciate an explanation
  2. How can I actually correctly implement the adapter(interface&&) constructor? I will probably need to create a copy of the object on the heap, otherwise it won't be persistent after the adapater constructor

Tested on ideone: http://ideone.com/Gz3ICk with C++14 (gcc-5.1)

PS: Yes the adapter class lacks a destructor that should delete obj created from the lambda constructor


Aucun commentaire:

Enregistrer un commentaire