Reputation: 103
I'm trying to make this piece of code work but i can't understood where I'm wrong the following code won't print the "foo" and the "here I'm" strings
class scoped_thread
{
std::thread t;
public:
explicit scoped_thread(std::thread t_):t(std::move(t_))
{
std::cout<<"here I'm"<<std::endl;
if(!t.joinable())
throw std::logic_error("No thread");
}
~scoped_thread()
{
t.join();
}
scoped_thread(scoped_thread const&)=delete;
scoped_thread& operator=(scoped_thread const&)=delete;
};
void foo(){
std::cout<<"foo"<<std::endl;
}
scoped_thread t1(std::thread(foo));
it simply won't execute the constructor.
if I change the last lines to
class foo1{
public:
void foo(){
std::cout<<"foo"<<std::endl;
}
}
scoped_thread t1(std::thread(&foo1::foo,&foo1));
the thread foo start to work.
i'm using mingw 4.8.1 and c++11 flag of the compiler where I'm wrong? I'have tried to figure what constructor must I use but up to now I haven't found it
Upvotes: 1
Views: 269
Reputation: 234654
This is known as the Most Vexing Parse.
Basically the compiler treats scoped_thread t1(std::thread(foo));
as a function declaration (declaring a function with a single std::thread
argument named foo
). It can be either a function declaration or a variable definition, but the rules of the language state that anything that can be both is a function declaration.
The traditional fix has been to add extra parentheses, like so scoped_thread t1((std::thread(foo)));
making it so that it cannot be parsed as a function declaration anymore. With C++ you can also use list-initialization instead, which doesn't fall prey to the Most Vexing Parse (though it has its own issues), like so scoped_thread t1{std::thread(foo)};
.
Upvotes: 1