AnkitG AnkitG - 22 days ago 7
C++ Question

How to access Singleton class member functions using different threads?

I am trying to run print() and print(char ch) methods on different threads with singleton instance .

Can any body help me out why I am getting errors:-



error C3867: 'Singleton::print': function call missing argument list; use '&Singleton::print' to create a pointer to member

error C3867: 'Singleton::print': function call missing argument list; use '&Singleton::print' to create a pointer to member

error C2661: 'std::thread::thread' : no overloaded function takes 2 arguments

Also help me in correcting out the following code for me.






class Singleton
{
private:
Singleton()
{}
static Singleton* singletonInstance;
public:
static Singleton* getSingletonInstance();
void print()
{
std::this_thread::sleep_for(std::chrono::milliseconds(500));
for (int i = 0; i < 100000; i++)
{
cout<<i<<endl;
}
}
void print(char ch)
{
std::this_thread::sleep_for(std::chrono::milliseconds(500));
for (int i = 0; i < 100000; i++)
{
cout<<ch<<" "<<i<<endl;
}
}
};
Singleton* Singleton::singletonInstance = nullptr;
Singleton* Singleton::getSingletonInstance()
{
if(!singletonInstance)
singletonInstance=new Singleton();

return singletonInstance;
}

int main()
{
std::thread t1(Singleton::getSingletonInstance()->print);
std::thread t2(Singleton::getSingletonInstance()->print,'T');
t1.join();
t2.join();
return 0;
}

Answer Source

The posted Code have tow problems:

1- the manner you are passing the function pointer to the threads is wrong:

std::thread t1(Singleton::getSingletonInstance()->print);

and the compiler is complaining and giving you a hint how do you have to pass the function pointer to the thread. it says: use '&Singleton::print' to create a pointer to member

Also step1 you have to pass your function pointer in the following manner:

std::thread t1(&Singleton::print);

Step2: setting the object of the Sigleton class, the function pointer belong to.

std::thread t1(&Singleton::print, Singleton::getSingletonInstance());

But that will function only if you haven't overloaded the function print, because the compiler can not find out, which print do you willing to call.

Also now we comes to second problem: how to solve the problem of overloaded functions?

you have tow possibilities:

1- you tell the compiler with help of casting which function you want to call:

int main()
{
    using print1 = void (Singleton::*)();
    using print2 = void (Singleton::*)(char);
    std::thread t1(print1(&Singleton::print), Singleton::getSingletonInstance());
    std::thread t2(print2(&Singleton::print), Singleton::getSingletonInstance(), 'T');
    t1.join();
    t2.join();
    return 0;
}

2- you use lambda functions and call the function directly:

int main()
{
    auto *s = Singleton::getSingletonInstance();
    std::thread t1([&s](){s->print();});
    std::thread t2([&s]() {s->print('T');});
    t1.join();
    t2.join();
    return 0;
}

The second one is smarter and easier to understand