C++11标准库thread构造函数浅析

@著作权归作者所有:来自CSDN博客作者大胡子的艾娃的原创作品,如需转载,请注明出处https://blog.csdn.net/qq_43148810,否则将追究法律责任。
如有错误的地方欢迎指正,谢谢!

一、标准库Thread内容(函数内部实现内容已摘去)

class thread
	{	// class for observing and managing threads
public:
	class id;
	typedef void *native_handle_type;
	thread() noexcept;
	template<class _Fn,
		class... _Args,
		class = enable_if_t<!is_same_v<remove_cv_t<remove_reference_t<_Fn>>, thread>>>
		explicit thread(_Fn&& _Fx, _Args&&... _Ax)
		{	// construct with _Fx(_Ax...)
		_Launch(&_Thr,
			_STD make_unique<tuple<decay_t<_Fn>, decay_t<_Args>...> >(
				_STD forward<_Fn>(_Fx), _STD forward<_Args>(_Ax)...));
		}
	~thread() noexcept;
	thread(thread&& _Other) noexcept
		: _Thr(_Other._Thr);
	thread& operator=(thread&& _Other) noexcept;
	thread(const thread&) = delete;
	thread& operator=(const thread&) = delete;
	void swap(thread& _Other) noexcept;
	_NODISCARD bool joinable() const noexcept;
	void join();
	void detach();
	_NODISCARD id get_id() const noexcept;
	_NODISCARD static unsigned int hardware_concurrency() noexcept;

	_NODISCARD native_handle_type native_handle();

private:
	thread& _Move_thread(thread& _Other);
	_Thrd_t _Thr;
	};

二、Thread类简单介绍
在介绍那个很复杂的构造函数前我们大致了解一下该类。
1、以下含义为thread被创建出来后不能进行拷贝和拷贝赋值,但是有move语义(c++11重要特性)。

thread(thread&& _Other) noexcept
	: _Thr(_Other._Thr);
thread& operator=(thread&& _Other) noexcept;
thread(const thread&) = delete;
thread& operator=(const thread&) = delete;
void swap(thread& _Other) noexcept;

2、常用接口(不是本篇的主题,将在另外文章中讲到)

void join();
void detach();
_NODISCARD id get_id() const noexcept;
_NODISCARD static unsigned int hardware_concurrency() noexcept;

三、复杂而重要的构造函数(本文的主题)

template<class _Fn,
		class... _Args,
		class = enable_if_t<!is_same_v<remove_cv_t<remove_reference_t<_Fn>>, thread>>>
		explicit thread(_Fn&& _Fx, _Args&&... _Ax)
		{	// construct with _Fx(_Ax...)
		_Launch(&_Thr,
			_STD make_unique<tuple<decay_t<_Fn>, decay_t<_Args>...> >(
				_STD forward<_Fn>(_Fx), _STD forward<_Args>(_Ax)...));
		}

1、模板参数部分

template<class _Fn,
		class... _Args,
		class = enable_if_t<!is_same_v<remove_cv_t<remove_reference_t<_Fn>>, thread>>>

1)class _Fn是设想匹配的是可调用对象(函数、成员函数、函数对象、lambda表达式)等。
2)class… _Args,匹配可调用对象的参数列,为C++11的重要特性Variadic Templates(…)和元组tuple。
3)以下内容我们由内到外一层一层分析(对萃取机和元编程要稍作了解)

class = enable_if_t<!is_same_v<remove_cv_t<remove_reference_t<_Fn>>, thread>>

a、remove_reference_t<_Fn>为退化_Fn的引用和右值引用。
b、remove_cv_t<#a#>在a的基础上再退化_Fn的const和volatile
c、is_same_v<#b#, thread>在b的基础上判断_Fn和thread是否为同种类型。
d、enable_if_t<!#c#>若c的结果为false则该构造函数模板匹配成功,否则失败。
小结:这么一大串是为了不和其他构造发生二义性,使得“1)”中_Fn为可调用对象的设想为真。
不同版本VS源码稍有差别,核心思想不会变。

四、延伸探讨

// construct with _Fx(_Ax...)
		_Launch(&_Thr,
			_STD make_unique<tuple<decay_t<_Fn>, decay_t<_Args>...> >(
				_STD forward<_Fn>(_Fx), _STD forward<_Args>(_Ax)...));

该构造函数的实现部分有兴趣的也可以研究研究。

更多内容请关注个人博客:https://blog.csdn.net/qq_43148810

上一篇:LeetCode1


下一篇:Java-面向对象_Object类的equals方法(3)