Is it possible to have overloads for functions that we need to span using threads ?
I have a simple class called Complex.
class Complex
{
public:
Complex():realPart_(0), imagPart_(0){}
Complex(double rp, double ip) : realPart_(rp), imagPart_(ip) {}
double & real() { return realPart_;}
double & imag() { return imagPart_;}
const double & real() const { return realPart_;}
const double & imag() const { return imagPart_;}
double square() const {return realPart_*realPart_ - imagPart_*imagPart_;}
void display() const
{
std::cout << "Square of the Complex number (" << realPart_ << ") + i (" << imagPart_ << " ) is " << square() << std::endl;
}
void display(unsigned nTimes) const {while(nTimes-- > 0)display();}
private:
double realPart_;
double imagPart_;
};
void Test3()
{
Complex c1(1, 0.74), c2(2, 0.35);
std::thread sqCalc1(&Complex::display, &c1);
std::thread sqCalc2(&Complex::display, &c2);
sqCalc1.join();
sqCalc2.join();
}
I get errors when I build this code.
error C2661: 'std::thread::thread' : no overloaded function takes 2 arguments
If there is no overloaded display function that takes an unsigned then the code I have shown works fine.
Contrary to some comments on the question, this is not a problem of C++11 restricting the ctor argument list, nor is it a compiler problem. std::thread constructor may take a pointer-to-member-function, followed by the object reference/pointer on wich the member function shall be called, followed by member function arguments (if there are any).
The problem at hand is just a disambiguation issue, just by seeing
&Complex::display
, the compiler has no chance to knwo which of the overloads you mean, because while deducting the template arguments it does not know that inside the constructor the function pointer will be called with the other arguments and that therefore only the unary or 0-ary member function makes sense.2 Possible solutions have been shown by bluescarni and billz:
A third possibility would be to explicitly specify the template parameter of the function pointer, but sadly it is not possible to explicitly instantiate templated constructors:
However, this would not make much difference to the explicit cast and argument deduction. and I prefer using lambdas anyways, in all cases, even if there is no such ambiguity, just because you can put a breakpoint right before the function call.
Maybe typedeffing and casting could help?
lambda can be used here, you could call any object function and pass arguments in as well:
The problem is nothing to do with
std::thread
(the error is misleading), as can be shown by rearranging the code:The error will be on the first line now, because as other answers have said, the expression
&Complex::display
refers to an overloaded function and the compiler doesn't know which one you mean.You can select the desired overload by telling the compiler the type of the function you are trying to call, with a cast or like this:
Now you've explicitly requested the
display
overload that returnsvoid
and takes no arguments.If your compiler supports C++11 alias declarations you can make that easier to read:
Although it is not about overriding member function, the only way to thank @billz for the lambda solution is to contribute with "my" code, that is the simplest case of the thread-call problem, again, solved with lambdas as proposed above.