1

ALL,

In myclass.cpp

MyClass::Initialize()
{
    m_thread = new std::thread( &Foo::func, *this );
}

In foo.cpp:

void Foo::func(MyClass &obj)
{
    // some processing
    // which involves modifying `obj`
}

I am getting a compiler error on gcc:

error: no type named 'type' in 'class std::result_of<std::_Mem_fn<void (Foo::*)(MyClass&)>(Foo*, MyClass)>'
       typedef typename result_of<_Callable(_Args...)>::type result_type;
                                                             ^

TIA!

Igor
  • 5,620
  • 11
  • 51
  • 103
  • 1
    Possible duplicate of [Start thread with member function](https://stackoverflow.com/questions/10673585/start-thread-with-member-function) – vandench Jul 26 '19 at 22:25
  • That function needs two arguments. One for the `Foo` object to call it on, and one for `obj`. The code only passes one argument. – Pete Becker Jul 26 '19 at 22:27
  • @PeteBecker, what would be the syntax? Thx. – Igor Jul 26 '19 at 22:39
  • @vandench, no, its not a dup. I am using 2 objects whereas the referenced question has only one. – Igor Jul 26 '19 at 22:41
  • In addition to a `Foo` instance, you need `std::ref(*this)`. – Jarod42 Jul 26 '19 at 22:48
  • @Igor it still applies, you have to pass the `this` as the first parameter, then you can pass all other parameters after that. In the C++ ABI’s I’m almost familiar with (MS x64) of `this` is a memory address passed `rcx`. Because of that you have to pass along that pointer, the C++ standard is setup to handle that for threads with as much ease as possible. – vandench Jul 26 '19 at 22:50
  • @vandench: That really makes little sense. First off, an ABI is an irrelevant detail. The exact same code works on ARM, because the syntax is defined by the C++ Standard, not the ABI. As for passing `this` first, note that the first argument has to be a `Foo&`, but `this` is a `MyClass*` inside `MyClass::initialize` – MSalters Jul 26 '19 at 23:05
  • @MSalters The ABI has everything to do with it, the pointer still has to be passed, it’s up to the ABI on how it’s done, but the standard understands that inherent need. If the pointer was never passed you would be essentially dealing with a null object. – vandench Jul 26 '19 at 23:13
  • I should clarify what I mean by `this`, I’m not talking about the thing that created the thread, but the pointer that the member function being run will use to access all of its class data. If you ever decompile C++ code it becomes pretty apparent that it is just a pointer passed through `rcx`, hex-rays even names it `this` and marks the function calling convention as `__thiscall`. – vandench Jul 26 '19 at 23:18

1 Answers1

3

In order to call Foo::func it needs a an object of type Foo to call it with. So you have to ask yourself, does func actually need to be a member function, or a non-static one at that? If you have a Foo object that you want to call it with, you would pass it as the second argument.

As for the third, you would pass *this, but since std::thread makes copies of each of its arguments, you will need to use a reference wrapper and pass it that way:

m_thread = new std::thread( &Foo::func, foo, std::ref(*this) );
David G
  • 94,763
  • 41
  • 167
  • 253