c++ - std::enable_if and std::shared_ptr -


goal: having function dispatching working intended. minimal example code should speak itself. want support tasks: named task, implemented in own class, , simpler task, specified using lambda. ideally, can converted std::function<void (void)> should work.

#include <iostream> #include <memory> #include <functional>  // base class tasks                                                                                                                                                                                                                  class basetask { public:   virtual void blah() = 0; };  // important enough tasks gets have                                                                                                                                                                                         // own class.                                                                                                                                                                                                                                 class namedtask : public basetask { public:   virtual void blah()   {     std::cout << "hey !" << std::endl;   } };  // wrapper around simpler tasks. (lambda)                                                                                                                                                                                                     class generictask : public basetask { public:   generictask(const std::function<void (void)> fct) :     fct_(fct) {}    virtual void blah() override   {     fct_();   }  private:   std::function<void (void)> fct_; };  void enqueue(std::shared_ptr<basetask> t) {   // store in queue.                                                                                                                                                                                                                            // we'll call here sake of example                                                                                                                                                                                        t->blah(); }  template<typename callable> //typename std::enable_if<!std::is_base_of<basetask, callable>::value>::type                                                                                                                                                                   //typename std::enable_if<!std::is_base_of<std::shared_ptr<basetask>, callable>::value>::type                                                                                                                                                  void enqueue(const callable &c) {   auto t = std::make_shared<generictask>(c);   t->blah(); }  int main() {   auto named = std::make_shared<namedtask>();   enqueue(named); // doesn't compile: tries call templated enqueue.                                                                                                                                                                     enqueue([] () -> bool { std::cout << "lamda" << std::endl; }); } 

problem: don't manage write proper enable_if template. commented lines in example tried.

  • the first 1 doesn't work because callable of type std::shared_ptr<namedtask>, not child of basetask.
  • the second 1 fails too, presumably because std::shared_ptr<namedtask> not derive std::shared_ptr<basetask>.

you have 2 cases: callable convertible shared_ptr<basetask>, or not. checking base incorrect shared_ptr<namedtask> not related class hierarchy shared_ptr<basetask>, can construct shared_ptr<basetask> it.

that is:

// convertible shared_ptr<basetask> void enqueue(std::shared_ptr<basetask> t);  // not convertible shared_ptr<basetask> template<typename callable> typename std::enable_if<     !std::is_convertible<callable, std::shared_ptr<basetask>>::value >::type enqueue(const callable &c); 

alternatively, can think of 2 cases constructible/not constructible:

template<typename callable> typename std::enable_if<     !std::is_constructible<std::shared_ptr<basetask>, callable>::value >::type enqueue(const callable &c); 

third alternative condition function template enqueue on callable 0 arguments:

template<typename callable> auto enqueue(const callable &c) -> decltype(c(), void()) 

Comments

Popular posts from this blog

IF statement in MySQL trigger -

c++ - What does MSC in "// appease MSC" comments mean? -

javascript - Blogger related post gadget image Resize s72-c [ Need Expert Help ] -