-1

I am new to C++, I need to use class object' member function as a thread function, and the object is used in application class and object cannot be shared so it is a unique pointer. When I am trying to create the thread, I am getting the compilation error.

I cannot copy the code as is so just created a sample code snippet.

DerivedType<-Base3Type<-Base2Type<-Base1Type - DerivedType is declared as private in application class

class AppClass
{
private:
    std::unique_ptr<DerivedType> transport;
public:

}

AppClass::Open()
{

    transport= std::make_unique<DerivedType>(client, logger);

    std::thread receive(&DerivedType::receive, &transport, flag, 1000);//flag and 100 are arguments to DerivedType::receive function.
}

I am getting the following compilation error

/usr/include/c++/5.2.1/functional:634:20: **error: pointer to member type ‘void (Base1Type::Base2Type::Base3Type::DerivedType::)(std::shared_ptr<bool>, const short unsigned int&)’ incompatible with object type ‘std::unique_ptr<Base1Type::Base2Type::Base3Type::DerivedType>’**
  { return ((*__ptr).*_M_pmf)(std::forward<_Args>(__args)...); }
                    ^

/usr/include/c++/5.2.1/functional:634:60: **error: return-statement with a value, in function returning 'void' [-fpermissive]**
  { return ((*__ptr).*_M_pmf)(std::forward<_Args>(__args)...); }

Please let me know how to get it compiled and execute without crash. Thank you.

jww
  • 97,681
  • 90
  • 411
  • 885
enthu
  • 69
  • 11
  • please see the question in detail, it is not a direct straight forward member function usage issue, my issue involves unique pointer which makes it difficult to debug – enthu Sep 24 '18 at 19:43
  • 2
    `&DerivedType::receive` seems to expect a `std::shared_ptr`. Is that what you are trying to pass `transport` to? Is `receive` static? Please share a [MCVE], it would answer these questions. Note that `transport` is being passed by copy but isn't copyable. – François Andrieux Sep 24 '18 at 19:44
  • yes 'flag' is std::shared_ptr and receive is not a static function. Sorry I missed to mention &transport, which I edited now. – enthu Sep 24 '18 at 19:48
  • Then the [previously posted duplicate](https://stackoverflow.com/questions/10673585/start-thread-with-member-function) is relevant. You need to pass some form of instance to call a member function. `&transport` is a pointer to a `unique_ptr` and a step in the wrong direction. The rest of my previous concerns still stand. You can't copy a `std::unique_ptr` so change `receive` and pass it by reference (don't forget `std::ref`) or store transport in a `std::shared_ptr`. Again, please take the time to write a [MCVE] so that this question can be answered properly and we can skip the back and forth. – François Andrieux Sep 24 '18 at 19:54
  • thanks @Francois, sorry i didn't have time to get minimal example. – enthu Sep 24 '18 at 20:27

1 Answers1

2

You want to call member function as body of thread so you need to pass pointer to DerivedType object (use unique_ptr::get method), not pointer to unique_ptr, write

std::thread receive(&DerivedType::receive, transport.get(), flag, 1000);//
                                           ^^^^^^^^^^^^^^^

and execute without crash.

now your code will be aborted by terminate function while calling destructor of thread at the end of Open method because your thread is in joinable state. So you need to choose

  1. call join on receive thread object, then you wait in Open method (it doesn't make sense)
  2. call detach on receive object but then you must ensure that transport object will not be destroyed before task started in receive thread ends.
rafix07
  • 20,001
  • 3
  • 20
  • 33
  • thank you so much, its working with detach option – enthu Sep 24 '18 at 20:26
  • You can also make thread receive as member data of app class and then you can call join on receive in somewhere in your code - it is another solution instead of calling detach. – rafix07 Sep 24 '18 at 20:29
  • 1
    @enthu Think really hard before using `detach`. After you `detach` you no longer have any control over the thread. The most significant downside is the program can now exit before the thread does and you have no way to stop it from happening. – user4581301 Sep 24 '18 at 20:47
  • @enthu A proper solution usually doesn't need to use `detach`. It's more likely that it's a red flag that there is a problem with your design which will eventually become apparent. – François Andrieux Sep 25 '18 at 02:47
  • 1
    yes i got rid of detach, used thread receive member of app class, thank you – enthu Sep 27 '18 at 19:32