Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling overloaded member functions using std::thread

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.

like image 369
Ram Avatar asked Jan 11 '13 10:01

Ram


People also ask

How function calls are matched with overloaded functions?

The process of matching function calls to a specific overloaded function is called overload resolution. Just because there is no exact match here doesn't mean a match can't be found -- after all, a char or long can be implicitly type converted to an int or a double .

Can member functions be overloaded?

Function declarations that differ only by its return type cannot be overloaded with function overloading process. Member function declarations with the same parameters or the same name types cannot be overloaded if any one of them is declared as a static member function.

Can member function be overloaded in C++?

Operator overloading of member function When overloading an operator using a member function: The overloaded operator must be added as a member function of the left operand. The left operand becomes the implicit *this object. All other operands become function parameters.

What is calling overloaded function?

The function call operator, when overloaded, does not modify how functions are called. Rather, it modifies how the operator is to be interpreted when applied to objects of a given type. You overload the function call operator, operator() , with a nonstatic member function that has any number of parameters.


2 Answers

The problem is nothing to do with std::thread (the error is misleading), as can be shown by rearranging the code:

auto memfunc = &Complex::display;
std::thread sqCalc1(memfunc, &c1);
std::thread sqCalc2(memfunc, &c2);

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:

void (Complex::*memfunc)() const = &Complex::display;
std::thread sqCalc1(memfunc, &c1);
std::thread sqCalc2(memfunc, &c2);

Now you've explicitly requested the display overload that returns void and takes no arguments.

If your compiler supports C++11 alias declarations you can make that easier to read:

using memfunc_type = void (Complex::*)() const;
memfunc_type memfunc = &Complex::display;
std::thread sqCalc1(memfunc, &c1);
std::thread sqCalc2(memfunc, &c2);
like image 199
Jonathan Wakely Avatar answered Oct 02 '22 14:10

Jonathan Wakely


lambda can be used here, you could call any object function and pass arguments in as well:

int main()
{
    Complex c1(1, 0.74), c2(2, 0.35);

    std::thread sqCalc1([=]{c1.display();});
    std::thread sqCalc2([=]{c2.display(3);});

    sqCalc1.join();
    sqCalc2.join();
    return 0;
}
like image 36
billz Avatar answered Oct 02 '22 12:10

billz