0

Edit: The correct title should have been "Calling overloaded true virtual function in base class", as that was a big part of the problem.

I have a base class with a true virtual function and a couple of other, normal ones. One of the normal ones calls the virtual function in a thread, and I get an error in that line, which I don't understand. I guess it has something to do with the thread, but as the base class is abstract, and every derived class has to actually implement the virtual function, there should be no problem. Maybe it's something completely different. This is more or less what it looks like:

class Base {
    virtual int getInfo(int a) = 0; // the culprit?

    void getInfo();         // is implemented, calls getInfo(int); Does  
                            // actually have the same name. Works perfectly fine.

    void getThreadedInfo(); // for details, see below

}

// ..later..

Base::getThreadedInfo() {
    ...
    for(int i=0; i<maxThreads; i++) {
        threads.push_back(thread(getInfo, i)); // this is line 85
    }
    ...
}

The complete error message is:

Error   1   error C3867: 'Base::getInfo': function call missing argument list; use '&Base::getInfo' to create a pointer to member   
c:\path\to\base.cpp 85  1   Project

Error   2   error C2661: 'std::thread::thread' : no overloaded function takes 2 arguments   
c:\path\to\base.cpp 85  1   Project
Arne
  • 17,706
  • 5
  • 83
  • 99

2 Answers2

1

You may use something like:

threads.push_back(std::thread(static_cast<int (Base::*)(int)>(&Base::getInfo), this, i));

as &Base::getInfo is ambiguous.

Jarod42
  • 203,559
  • 14
  • 181
  • 302
1

You have a couple different things going on.

The first, simplest one to fix is what the first error message is telling you about--you need to use the & operator with getInfo in thread's argument list to create a function pointer.

The second issue is that the call to getInfo in thread's contructor needs an additional argument. In addition to the explicit int a, since getInfo is not static, it takes an implicit Base* this. So this needs to be added.

The third, trickiest problem is that Base has two overloads of getInfo, so you need to make it explicit which one you want.

Putting all three things together, you need to have... exactly what this answer said while I was typing. :)

Community
  • 1
  • 1
dlf
  • 9,045
  • 4
  • 32
  • 58
  • I don't get why I have to add the & and the 'this'-argument. In the thread-documentation on cplusplus.com the initialize threads with std::thread second (bar,0); // spawn new thread that calls bar(0). Is it because I am calling a member function? If yes .. why does it work that way? – Arne Jun 09 '14 at 17:30
  • Think about it this way: If you didn't pass `this`, how would the compiler know which `Base` object you wanted to call `getInfo` on? When you call the function the normal way with something like `o.getInfo(3)`, it's obvious that the object to the left of the operator should be used as `this`. But when you're using the function generically, you have to provide a value for `this` explicitly. – dlf Jun 09 '14 at 17:35
  • My previous comment only addressed half your question. In response to the other half (`&`), yes, the difference is that you're dealing with a member function here. – dlf Jun 09 '14 at 17:37
  • I guess I assumed that "this" was implicit, as the member function was the only function of that name visible in the scope of the call. But it does make sense, thank you. – Arne Jun 09 '14 at 17:38
  • Ok; I can see why someone would assume that. You're right, *in theory*, if you're binding to a member function of class `C` from within another member function of `C`, the `this` value for the function call could be populated implicitly with the current `this`. But then some sort of actual change to the language would be required in order to implement `thread`, `bind`, and anything else that uses member function pointers. In any case, it doesn't work like that. – dlf Jun 09 '14 at 17:41
  • I still haven't answered you whole question. I'm actually not sure why you're allowed to omit the `&` with free functions but not member functions (you still *can* use it with free functions if you want to). – dlf Jun 09 '14 at 17:46
  • A comment on [this question](http://stackoverflow.com/questions/18312186/if-ampersands-arent-needed-for-function-pointers-why-does-boostbind-require) claims the `&` is only optional with free functions in order to allow compatibility with C. – dlf Jun 09 '14 at 17:49
  • Very interesting. Thank you for digging so deep into it, I appreciate it! – Arne Jun 09 '14 at 22:17