0

I would like to pass std::thread temporary object directly to my ThreadGuard class but somehow that is not producing any output, however if I first create local std::thread variable and pass that to constructor then it is working fine. So my question is can't we pass temporary thread to function taking rvalue reference parameter ?

#include <iostream>
#include <thread>
using namespace std;

class ThreadGuard
{
    private:
        std::thread& m_t;
    public:
        ThreadGuard(std::thread& t):m_t(t)
        {
            std::cout<<"By lvalue ref constructor "<<std::endl;
        }
        ThreadGuard(std::thread&& t):m_t(t)
        {
            std::cout<<"By rvalue ref constructor "<<std::endl;
        }
        ~ThreadGuard()
        {
            if(m_t.joinable())
            {
                m_t.join();
            }
        }
    
};
void foo()
{
    std::cout<<"Inside foo..."<<std::endl;
}
int main()
{
    //This is working
    //std::thread th(foo);
    //ThreadGuard t1(th);
    //This is not giving any output
    ThreadGuard t(std::thread(foo));
    
    return 0;
}
PapaDiHatti
  • 1,841
  • 19
  • 26

1 Answers1

2

What you have just come across is C++'s most vexing parse syntax.

The compiler thinks that you have declared a function t which returns a ThreadGuard and takes an argument foo of type std::thread:

ThreadGuard t(std::thread foo);

A possible solution would be to use curly braces for initialization, as such:

ThreadGuard t(std::thread{foo});
Lev Leontev
  • 2,538
  • 2
  • 19
  • 31