Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why std::thread accepts generic lambdas but not templated functions (without explicit instantiation)?

Why is it legal to pass generic lambdas to std::thread() without any specialization, while, on the other hand, this is illegal with function templates.

The following demonstrates my query.

#include <thread>

template <class T>
void f(T t)
{
}

int main()
{
    std::thread t([](auto i){}, 1);  // Works
    std::thread t(f, 1);          // Doesn't work
    std::thread t(f<int>, 1);     // Works

    t.join();
    return 0;
}
like image 916
alex35833 Avatar asked Sep 17 '25 12:09

alex35833


1 Answers

C++ consists of many different kinds of things. Some of these things are: objecs, types, and templates. They are completely different things, that serve their own distinct, unique purposes. There's a right place in a C++ program to use an object, a right place to use a type, and a right place to use a template. When you have a right place for an object, you can't use a type or a template. When you have a right place to use a type you can't use an object or a template. When you have a right place to use a template you can't use an object or a type. This is fundamental to C++.

The parameters to a function call, or a constructor, are always objects. They are never types, or templates.

    std::thread t([](auto i){}, 1);  // Works

Both parameters are objects. This is correct. A lambda is an object, an instance of a unique, anonymous type. 1 is also an object: an integer whose value is 1.

    std::thread t(f, 1);          // Doesn't work

f is not an object. It is a template.

    std::thread t(f<int>, 1);     // Works

This f<int> is an object, a pointer to a function that was instantiated from a template.

An identifier that corresponds to a name of a template, by itself, results in a template. It does not result in a type, or an object. When you specify template parameters you end up with a type, and in a special case of a type that refers to a template function you get a pointer to the template function instance, an object (just like using the name of an ordinary non-template function, by itself, gives you a pointer to that function).

like image 131
Sam Varshavchik Avatar answered Sep 19 '25 05:09

Sam Varshavchik