0

This title might be a little confusing, but I am hurrying with the explanation.

I wanted to ask you guys why having a class like that:

class scoped_thread2
{
    std::thread t;
public:
    explicit scoped_thread2(std::thread t_) : t(std::move(t_))
    {
    }

    ~scoped_thread2() {
        t.join();
    }
};

I was calling constructor of scoped_thread2 like this:

scoped_thread2 thread_test{ std::thread(do_something) };

Where do_something was a simple void function that actually did nothing.

void do_something()
{
    return;
}

So I'm asking, why the first initialization works, and I clearly see in Visual Studio's debugger that we are going into scoped_thread2's constructor, but in this case:

scoped_thread2 thread_test2(std::thread(do_something));

It does not work. I found that it's somehow related to uniform initialization that was introduced in C++11, but I couldn't find a good explanation that would explain this difference to me clearly. Anyone?

todovvox
  • 170
  • 10
  • 3
    IIRC, the 2nd case is a result of the ["most vexing parse"](https://www.fluentcpp.com/2018/01/30/most-vexing-parse/). It is actually a *function declaration*, not an *object declaration*, as the 1st case is. The 2nd case is declaring a *function* named `thread_test2`, that takes in a `std::thread` named `do_something`, and returns a `scoped_thread2`. Uniform Initialization using curly braces was introduced, in part, to help avoid ambiguities caused by MVP. The 1st case is not subject to MVP because of the braces. – Remy Lebeau Sep 15 '22 at 20:33

0 Answers0