std :: thread构造函数第三个模板参数的目的是什么?

Rom*_*man 14 c++ multithreading templates c++11

这是std::thread构造函数声明的方式(使用Visual Studio 2015):

template<class _Fn,
class... _Args,
class = typename enable_if<
    !is_same<typename decay<_Fn>::type, thread>::value>::type>
explicit thread(_Fn&& _Fx, _Args&&... _Ax)
Run Code Online (Sandbox Code Playgroud)

没有问题就_Fn_Args,然而,第三class = ...混淆了我完全.它做什么,它是如何工作的以及它的用途是什么?

Yak*_*ont 16

这是使用SFINAE有条件地启用过载的示例.

如果第一个参数是类型,则不应将此重载视为重载解析std::thread.

请注意,不打算读取 C++标准头文件的原始源代码.它也不是为了模仿.C++编译器实现者可以在他们的std头实现中做很多事情,你不能也不应该在这些头之外做.其中最少的是启动变量,_后跟大写字母(在用户代码中被禁止).

检查默认参数的类型,如果_Fn是a std::thread,对相同的引用或对cv修改后的引用的引用.

typename enable_if<
!is_same<typename decay<_Fn>::type, thread>::value>::type>
Run Code Online (Sandbox Code Playgroud)

decay<_Fn>::type剥离参考和cv资格.它还将函数引用转换为指向函数的指针,将引用转换为指向第一元素的指针,但这在此并不重要.

假设_Fnthread&.我会评估:

typename enable_if<
!is_same<typename decay<thread&>::type, thread>::value>::type>
typename enable_if<
!is_same<thread, thread>::value>::type>
typename enable_if<
!true>::type>
typename enable_if<
false>::type>
/* substitution failure occurs */>
Run Code Online (Sandbox Code Playgroud)

enable_if<B>::type如果只存在Btrue; when _Fn是一个线程,它是假的,因此在重载解析期间存在替换失败.

SFINAE意味着替换失败不是错误,而不是编译器抱怨,它只是从考虑中删除了这个重载.并且找到了thread(thread const&)(我认为是=deleteed)构造函数.


son*_*yao 5

第三个未命名的模板参数有一个默认值,用于通过SFINAE满足std :: thread构造函数的以下要求,以避免在调用移动构造函数时出现干扰.

如果std::decay_t<Function>类型相同,则此构造函数不参与重载解析std::thread.