2

I am using TRI DDS - here is the prototype for the function I am trying to call:

template<typename T , typename Functor >
dds::sub::cond::ReadCondition::ReadCondition  (
  const dds::sub::DataReader< T > &  reader,  
  const dds::sub::status::DataState &  status,  
  const Functor &  handler  
)

So I have a class that looks a bit like this (with load of irrelevant stuff omitted):

MyClass test{
public:
    test(){... mp_reader = ...}; // not complete

    start_reader()
    {
        dds::sub::cond::ReadCondition rc(*mp_reader,
                                         dds::sub::status::DataState::any(),
                                         do_stuff());  // This does not work
    }

    void do_stuff() {...}
private:
    dds::sub::DataReader* mp_reader;

}

So I just tried to pass in the function do_stuff().. I know this won't work, but I am not sure what to put in here in place of the const & functor parameter. Can I pass a member function in? - how do I specify the instance of the class?

I tried putting a lambda in there and it worked - but I can't access mp_reader in the lambda because it is not in the scope of the lambda. But anyway I don't really want to use a lambda I really want to use a function (so, eventually I might be able to pass in an external one).

Please see here for the RTI DDS function. Here is what it says about the functor type:

"Any type whose instances that can be called with a no-argument function call (i.e. f(), if f is an instance of Functor). Examples are functions, types that override the operator(), and lambdas <<C++11>>. The return type has to be void"

SergeyA
  • 61,605
  • 5
  • 78
  • 137
code_fodder
  • 15,263
  • 17
  • 90
  • 167
  • 1
    What is the type of `Functor`? Is it a template argument? Is it a class type? – François Andrieux Mar 06 '18 at 18:40
  • @FrançoisAndrieux From what I can tell it is any function that returns a void (e.g. `void f()`). I will add the link to ReadCondition() constructor.... – code_fodder Mar 06 '18 at 18:42
  • The solution to your problem will depend on whether `Functor` is template parameter or not. – R Sahu Mar 06 '18 at 18:44
  • 2
    Instead of `do_stuff()`, can you use `[this](){ this->do_stuff(); }` ? – Eljay Mar 06 '18 at 18:44
  • @G.M. when I compile the with a lambda that uses mp_reader I get the compiler error: `a lambda capture variable must be from an enclosing function scope` ... that was my interpretation of that error message :p – code_fodder Mar 06 '18 at 18:47
  • @Eljay that compiled! - thanks. I guess if I need to pass a member function from a different class I can also do that by passing in the "this" instance of that other class and the function-member pointer? +1 thanks - feel free to write that as an answer I'll mark it up. – code_fodder Mar 06 '18 at 18:51
  • @code_fodder • you can give R Sahu credit, I see the answer is already written up. :-) The lambda is a newer, better, cleaner-syntax C++11 way than using the older style `std::bind` (pre-C++11, but now arguably unnecessary). – Eljay Mar 06 '18 at 19:46

2 Answers2

5

You can use a lambda function with a capture.

dds::sub::cond::ReadCondition rc(*mp_reader,
                                 dds::sub::status::DataState::any(),
                                 [this](){ this->do_stuff(); });
R Sahu
  • 204,454
  • 14
  • 159
  • 270
2

You could use std::bind (see http://en.cppreference.com/w/cpp/utility/functional/bind)

dds::sub::cond::ReadCondition rc(*mp_reader,
                                 dds::sub::status::DataState::any(),
                                 std::bind(&MyClass::do_stuff, this));

See also How to directly bind a member function to an std::function in Visual Studio 11?

Rob Starling
  • 3,868
  • 3
  • 23
  • 40
  • 1
    It's recommended to avoid `std::bind` in favor of lambdas. https://stackoverflow.com/a/36596295/1896169 – Justin Mar 06 '18 at 19:01
  • 1
    Thanks for pointing this out! I think it's still a valid answer for completeness, though. – Rob Starling Mar 06 '18 at 19:38
  • ( Also, thanks again for the indirect link to the Lavavej video! The bit at https://youtu.be/zt7ThwVfap0?t=34m3s about lambdas effectively having copy constructors that can _reinitialize captures_ is fascinating. ) – Rob Starling Mar 06 '18 at 19:39