C++中thread调用“带mutex的类”的成员函数报错C2661:std::tuple解决方法

今天在做LeetCode的1114题《按序打印》,想在本地调试,写了如下代码:

#include <vector>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <functional>

using namespace std;

class Foo {
private:
	mutex m;
public:
	Foo() {
	}

	void first(function<void()> printFirst) {

		// printFirst() outputs "first". Do not change or remove this line.
		printFirst();
	}

	void second(function<void()> printSecond) {

		// printSecond() outputs "second". Do not change or remove this line.
		printSecond();
	}

	void third(function<void()> printThird) {

		// printThird() outputs "third". Do not change or remove this line.
		printThird();
	}
};

int main() 
{
	//
	function<void()> fun[3];
	fun[0] = []() {printf("1"); };
	fun[1] = []() {printf("2"); };
	fun[2] = []() {printf("3"); };

	vector<thread> vect;
	vector<int> vec{ 2,1,3 };

	Foo foo;

	using Func = void(Foo::*)(function<void()>);
	vector<Func> pmemfunc{ &Foo::first,&Foo::second,&Foo::third };

	for (auto i : vec)
	{
		vect.push_back(thread(pmemfunc[i-1],foo,fun[i-1]));
	}

	for (auto& t : vect)
		t.join();

	system("pause");
	return 0;
}

vect中插入3个线程对象,线程中调用类成员函数,之后进行join。题目所给的Foo类,只要加上一个mutex成员,编译就不通过,报错:

C2661 “std::tuple<void (__thiscall
Foo:: * )(std::function<void (void)>),Foo,std::function<void
(void)>>::tuple”: 没有重载函数接受 3 个参数 console_temp C:\Program Files
(x86)\Microsoft Visual
Studio\2019\Community\VC\Tools\MSVC\14.23.28105\include\memory 2057

之后参考了 https://stackoverrun.com/cn/q/12697417 。意思是说创建thread时,传入的类对象会触发拷贝动作,而mutex是不可拷贝对象,所以报错。把foo改为std::ref(foo)后,编译通过。

顺带给出这道题的一个解法:


#include <vector>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <functional>

using namespace std;

class Foo {
private:
	mutex m;
	condition_variable cv;
	bool b1;
	bool b2;
public:
	Foo() {
		b1 = false;
		b2 = false;
	}

	void first(function<void()> printFirst) {

		// printFirst() outputs "first". Do not change or remove this line.
		unique_lock<mutex> ul(m);
		printFirst();
		b1 = true;
		cv.notify_all();
	}

	void second(function<void()> printSecond) {

		// printSecond() outputs "second". Do not change or remove this line.
		unique_lock<mutex> ul(m);
		cv.wait(ul, [&]() {return b1; });
		printSecond();
		b2 = true;
		cv.notify_all();
	}

	void third(function<void()> printThird) {

		// printThird() outputs "third". Do not change or remove this line.
		unique_lock<mutex> ul(m);
		cv.wait(ul, [this]() {return b2; });
		printThird();
	}
};

int main() 
{
	function<void()> fun[3];
	fun[0] = []() {printf("1"); };
	fun[1] = []() {printf("2"); };
	fun[2] = []() {printf("3"); };

	vector<thread> vect;
	vector<int> vec{ 2,1,3 };

	Foo foo;

	using Func = void(Foo::*)(function<void()>);
	vector<Func> pmemfunc{ &Foo::first,&Foo::second,&Foo::third };

	for (auto i : vec)
	{
		vect.push_back(thread(pmemfunc[i-1],ref(foo),fun[i-1]));
	}

	for (auto& t : vect)
		t.join();

	system("pause");
	return 0;
}

运行结果:
在这里插入图片描述

tcw@tcw:~/code_file/code_test$ g++ test.cpp In file included from /usr/include/c++/7/future:39:0, from test.cpp:2: /usr/include/c++/7/thread: In instantiation of ‘static std::thread::_Invoker<std::tuple<typename std::decay<_Tp>::type, typename std::decay<_Args>::type ...> > std::thread::__make_invoker(_Callable&&, _Args&& ...) [with _Callable = std::packaged_task<int(int)>&; _Args = {int}; typename std::decay<_Tp>::type = std::packaged_task<int(int)>]’: /usr/include/c++/7/thread:127:22: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = std::packaged_task<int(int)>&; _Args = {int}]’ test.cpp:12:19: required from here /usr/include/c++/7/thread:258:4: error: no matching function for call to ‘std::tuple<std::packaged_task<int(int)>, int>::tuple(<brace-enclosed initializer list>)’ } }; ^ In file included from /usr/include/c++/7/mutex:38:0, from /usr/include/c++/7/future:38, from test.cpp:2: /usr/include/c++/7/tuple:1203:18: note: candidate: template<class _Alloc, class _U1, class _U2, typename std::enable_if<(_MoveConstructibleTuple<_U1, _U2>() && (! _ImplicitlyMoveConvertibleTuple<_U1, _U2>())), bool>::type <anonymous> > std::tuple<_T1, _T2>::tuple(std::allocator_arg_t, const _Alloc&, std::pair<_U1, _U2>&&) explicit tuple(allocator_arg_t __tag, const _Alloc& __a, ^~~~~ /usr/include/c++/7/tuple:1203:18: note: template argument deduction/substitution failed: In file included from /usr/include/c++/7/future:39:0, from test.cpp:2: /usr/include/c++/7/thread:258:4: note: candidate expects 3 arguments, 2 provided } }; ^ In file included from /usr/include/c++/7/mutex:38:0, from /usr/include/c++/7/future:38, from test.cpp:2: /usr/include/c++/7/tuple:1193:9: note: candidate: template<class _Alloc, class _U1, class _U2, typename std::enable_if<(_MoveConstructibleTuple<_U1, _U2>() && _ImplicitlyMoveConvertibleTuple<_U1, _U2>()), bool>::type <anonymous> > std::tuple<_T1, _T2>::tuple(std::allocator_arg_t, const _Alloc&, std::pair<_U1, _U2>&&) tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in) ^~~~~ /usr/include/c++/7/tuple:1193:9: note: template argument deduction/substitution failed: In file included from /usr/include/c++/7/future:39:0, from test.cpp:2: /usr/include/c++/7/thread:258:4: note: candidate expects 3 arguments, 2 provided } }; ^ In file included from /usr/include/c++/7/mutex:38:0, from /usr/include/c++/7/future:38, from test.cpp:2: /usr/include/c++/7/tuple:1183:18: note: candidate: template<class _Alloc, class _U1, class _U2, typename std::enable_if<(_ConstructibleTuple<_U1, _U2>() && (! _ImplicitlyConvertibleTuple<_U1, _U2>())), bool>::type <anonymous> > std::tuple<_T1, _T2>::tuple(std::allocator_arg_t, const _Alloc&, const std::pair<_U1, _U2>&) explicit tuple(allocator_arg_t __tag, const _Alloc& __a, ^~~~~ /usr/include/c++/7/tuple:1183:18: note: template argument deduction/substitution failed: In file included from /usr/include/c++/7/future:39:0, from test.cpp:2: /usr/include/c++/7/thread:258:4: note: candidate expects 3 arguments, 2 provided } }; ^ In file included from /usr/include/c++/7/mutex:38:0, from /usr/include/c++/7/future:38, from test.cpp:2: /usr/include/c++/7/tuple:1173:9: note: candidate: template<class _Alloc, class _U1, class _U2, typename std::enable_if<(_ConstructibleTuple<_U1, _U2>() && _ImplicitlyConvertibleTuple<_U1, _U2>()), bool>::type <anonymous> > std::tuple<_T1, _T2>::tuple(std::allocator_arg_t, const _Alloc&, const std::pair<_U1, _U2>&) tuple(allocator_arg_t __tag, const _Alloc& __a, ^~~~~ /usr/include/c++/7/tuple:1173:9: note: template argument deduction/substitution failed: In file included from /usr/include/c++/7/future:39:0, from test.cpp:2: /usr/include/c++/7/thread:258:4: note: candidate expects 3 arguments, 2 provided } }; ^ In file included from /usr/include/c++/7/mutex:38:0, from /usr/include/c++/7/future:38, from test.cpp:2: /usr/include/c++/7/tuple:1162:11: note: candidate: template<class _Alloc, class _U1, class _U2, typename std::enable_if<(_MoveConstructibleTuple<_U1, _U2>() && (! _ImplicitlyMoveConvertibleTuple<_U1, _U2>())), bool>::type <anonymous> > std::tuple<_T1, _T2>::tuple(std::allocator_arg_t, const _Alloc&, std::tuple<_U1, _U2>&&) explicit tuple(allocator_arg_t __tag, const _Alloc& __a, ^~~~~ /usr/include/c++/7/tuple:1162:11: note: template argument deduction/substitution failed: In file included from /usr/include/c++/7/future:39:0, from test.cpp:2: /usr/include/c++/7/thread:258:4: note: candidate expects 3 arguments, 2 provided } }; ^ In file included from /usr/include/c++/7/mutex:38:0, from /usr/include/c++/7/future:38, from test.cpp:2: /usr/include/c++/7/tuple:1152:2: note: candidate: template<class _Alloc, class _U1, class _U2, typename std::enable_if<(_MoveConstructibleTuple<_U1, _U2>() && _ImplicitlyMoveConvertibleTuple<_U1, _U2>()), bool>::type <anonymous> > std::tuple<_T1, _T2>::tuple(std::allocator_arg_t, const _Alloc&, std::tuple<_U1, _U2>&&) tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in) ^~~~~ /usr/include/c++/7/tuple:1152:2: note: template argument deduction/substitution failed: In file included from /usr/include/c++/7/future:39:0, from test.cpp:2: /usr/include/c++/7/thread:258:4: note: candidate expects 3 arguments, 2 provided } }; ^ In file included from /usr/include/c++/7/mutex:38:0, from /usr/include/c++/7/future:38, from test.cpp:2: /usr/include/c++/7/tuple:1140:11: note: candidate: template<class _Alloc, class _U1, class _U2, typename std::enable_if<(_ConstructibleTuple<_U1, _U2>() && (! _ImplicitlyConvertibleTuple<_U1, _U2>())), bool>::type <anonymous> > std::tuple<_T1, _T2>::tuple(std::allocator_arg_t, const _Alloc&, const std::tuple<_U1, _U2>&) explicit tuple(allocator_arg_t __tag, const _Alloc& __a, ^~~~~ /usr/include/c++/7/tuple:1140:11: note: template argument deduction/substitution failed: In file included from /usr/include/c++/7/future:39:0, from test.cpp:2: /usr/include/c++/7/thread:258:4: note: candidate expects 3 arguments, 2 provided } }; ^ In file included from /usr/include/c++/7/mutex:38:0, from /usr/include/c++/7/future:38, from test.cpp:2: /usr/include/c++/7/tuple:1128:2: note: candidate: template<class _Alloc, class _U1, class _U2, typename std::enable_if<(_ConstructibleTuple<_U1, _U2>() && _ImplicitlyConvertibleTuple<_U1, _U2>()), bool>::type <anonymous> > std::tuple<_T1, _T2>::tuple(std::allocator_arg_t, const _Alloc&, const std::tuple<_U1, _U2>&) tuple(allocator_arg_t __tag, const _Alloc& __a, ^~~~~ /usr/include/c++/7/tuple:1128:2: note: template argument deduction/substitution failed: In file included from /usr/include/c++/7/future:39:0, from test.cpp:2: /usr/include/c++/7/thread:258:4: note: candidate expects 3 arguments, 2 provided } }; ^ In file included from /usr/include/c++/7/mutex:38:0, from /usr/include/c++/7/future:38, from test.cpp:2: /usr/include/c++/7/tuple:1119:2: note: candidate: template<class _Alloc> std::tuple<_T1, _T2>::tuple(std::allocator_arg_t, const _Alloc&, std::tuple<_T1, _T2>&&) tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in) ^~~~~ /usr/include/c++/7/tuple:1119:2: note: template argument deduction/substitution failed: In file included from /usr/include/c++/7/future:39:0, from test.cpp:2: /usr/include/c++/7/thread:258:4: note: candidate expects 3 arguments, 2 provided } }; ^ In file included from /usr/include/c++/7/mutex:38:0, from /usr/include/c++/7/future:38, from test.cpp:2: /usr/include/c++/7/tuple:1115:2: note: candidate: template<class _Alloc> std::tuple<_T1, _T2>::tuple(std::allocator_arg_t, const _Alloc&, const std::tuple<_T1, _T2>&) tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in) ^~~~~ /usr/include/c++/7/tuple:1115:2: note: template argument deduction/substitution failed: In file included from /usr/include/c++/7/future:39:0, from test.cpp:2: /usr/include/c++/7/thread:258:4: note: candidate expects 3 arguments, 2 provided } }; ^ In file included from /usr/include/c++/7/mutex:38:0, from /usr/include/c++/7/future:38, from test.cpp:2: /usr/include/c++/7/tuple:1109:11: note: candidate: template<class _Alloc, class _U1, class _U2, typename std::enable_if<(_MoveConstructibleTuple<_U1, _U2>() && (! _ImplicitlyMoveConvertibleTuple<_U1, _U2>())), bool>::type <anonymous> > std::tuple<_T1, _T2>::tuple(std::allocator_arg_t, const _Alloc&, _U1&&, _U2&&) explicit tuple(allocator_arg_t __tag, const _Alloc& __a, ^~~~~ /usr/include/c++/7/tuple:1109:11: note: template argument deduction/substitution failed: In file included from /usr/include/c++/7/future:39:0, from test.cpp:2: /usr/include/c++/7/thread:258:4: note: candidate expects 4 arguments, 2 provided } }; ^ In file included from /usr/include/c++/7/mutex:38:0, from /usr/include/c++/7/future:38, from test.cpp:2: /usr/include/c++/7/tuple:1099:2: note: candidate: template<class _Alloc, class _U1, class _U2, typename std::enable_if<(_MoveConstructibleTuple<_U1, _U2>() && _ImplicitlyMoveConvertibleTuple<_U1, _U2>()), bool>::type <anonymous> > std::tuple<_T1, _T2>::tuple(std::allocator_arg_t, const _Alloc&, _U1&&, _U2&&) tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2) ^~~~~ /usr/include/c++/7/tuple:1099:2: note: template argument deduction/substitution failed: In file included from /usr/include/c++/7/future:39:0, from test.cpp:2: /usr/include/c++/7/thread:258:4: note: candidate expects 4 arguments, 2 provided } }; ^ In file included from /usr/include/c++/7/mutex:38:0, from /usr/include/c++/7/future:38, from test.cpp:2: /usr/include/c++/7/tuple:1089:11: note: candidate: template<class _Alloc, class _Dummy, typename std::enable_if<(std::_TC<std::is_same<_Dummy, void>::value, std::packaged_task<int(int)>, int>::_ConstructibleTuple<packaged_task<int(int)>, int>() && (! std::_TC<std::is_same<_Dummy, void>::value, std::packaged_task<int(int)>, int>::_ImplicitlyConvertibleTuple<packaged_task<int(int)>, int>())), bool>::type <anonymous> > std::tuple<_T1, _T2>::tuple(std::allocator_arg_t, const _Alloc&, const _T1&, const _T2&) explicit tuple(allocator_arg_t __tag, const _Alloc& __a, ^~~~~ /usr/include/c++/7/tuple:1089:11: note: template argument deduction/substitution failed: In file included from /usr/include/c++/7/future:39:0, from test.cpp:2: /usr/include/c++/7/thread:258:4: note: candidate expects 4 arguments, 2 provided } }; ^ In file included from /usr/include/c++/7/mutex:38:0, from /usr/include/c++/7/future:38, from test.cpp:2: /usr/include/c++/7/tuple:1077:2: note: candidate: template<class _Alloc, class _Dummy, typename std::enable_if<(std::_TC<std::is_same<_Dummy, void>::value, std::packaged_task<int(int)>, int>::_ConstructibleTuple<packaged_task<int(int)>, int>() && std::_TC<std::is_same<_Dummy, void>::value, std::packaged_task<int(int)>, int>::_ImplicitlyConvertibleTuple<packaged_task<int(int)>, int>()), bool>::type <anonymous> > std::tuple<_T1, _T2>::tuple(std::allocator_arg_t, const _Alloc&, const _T1&, const _T2&) tuple(allocator_arg_t __tag, const _Alloc& __a, ^~~~~ /usr/include/c++/7/tuple:1077:2: note: template argument deduction/substitution failed: In file included from /usr/include/c++/7/future:39:0, from test.cpp:2: /usr/include/c++/7/thread:258:4: note: candidate expects 4 arguments, 2 provided } }; ^ In file included from /usr/include/c++/7/mutex:38:0, from /usr/include/c++/7/future:38, from test.cpp:2: /usr/include/c++/7/tuple:1066:2: note: candidate: template<class _Alloc> std::tuple<_T1, _T2>::tuple(std::allocator_arg_t, const _Alloc&) tuple(allocator_arg_t __tag, const _Alloc& __a) ^~~~~ /usr/include/c++/7/tuple:1066:2: note: template argument deduction/substitution failed: In file included from /usr/include/c++/7/future:39:0, from test.cpp:2: /usr/include/c++/7/thread:258:4: note: cannot convert ‘std::forward<std::packaged_task<int(int)>&>((* & __callable))’ (type ‘std::packaged_task<int(int)>’) to type ‘std::allocator_arg_t’ } }; ^ In file included from /usr/include/c++/7/mutex:38:0, from /usr/include/c++/7/future:38, from test.cpp:2: /usr/include/c++/7/tuple:1059:28: note: candidate: template<class _U1, class _U2, typename std::enable_if<(_MoveConstructibleTuple<_U1, _U2>() && (! _ImplicitlyMoveConvertibleTuple<_U1, _U2>())), bool>::type <anonymous> > constexpr std::tuple<_T1, _T2>::tuple(std::pair<_U1, _U2>&&) explicit constexpr tuple(pair<_U1, _U2>&& __in) ^~~~~ /usr/include/c++/7/tuple:1059:28: note: template argument deduction/substitution failed: In file included from /usr/include/c++/7/future:39:0, from test.cpp:2: /usr/include/c++/7/thread:258:4: note:std::packaged_task<int(int)>’ is not derived from ‘std::pair<_T1, _T2>’ } }; ^ In file included from /usr/include/c++/7/mutex:38:0, from /usr/include/c++/7/future:38, from test.cpp:2: /usr/include/c++/7/tuple:1049:19: note: candidate: template<class _U1, class _U2, typename std::enable_if<(_MoveConstructibleTuple<_U1, _U2>() && _ImplicitlyMoveConvertibleTuple<_U1, _U2>()), bool>::type <anonymous> > constexpr std::tuple<_T1, _T2>::tuple(std::pair<_U1, _U2>&&) constexpr tuple(pair<_U1, _U2>&& __in) ^~~~~ /usr/include/c++/7/tuple:1049:19: note: template argument deduction/substitution failed: In file included from /usr/include/c++/7/future:39:0, from test.cpp:2: /usr/include/c++/7/thread:258:4: note:std::packaged_task<int(int)>’ is not derived from ‘std::pair<_T1, _T2>’ } }; ^ In file included from /usr/include/c++/7/mutex:38:0, from /usr/include/c++/7/future:38, from test.cpp:2: /usr/include/c++/7/tuple:1040:28: note: candidate: template<class _U1, class _U2, typename std::enable_if<(_ConstructibleTuple<_U1, _U2>() && (! _ImplicitlyConvertibleTuple<_U1, _U2>())), bool>::type <anonymous> > constexpr std::tuple<_T1, _T2>::tuple(const std::pair<_U1, _U2>&) explicit constexpr tuple(const pair<_U1, _U2>& __in) ^~~~~ /usr/include/c++/7/tuple:1040:28: note: template argument deduction/substitution failed: In file included from /usr/include/c++/7/future:39:0, from test.cpp:2: /usr/include/c++/7/thread:258:4: note:std::packaged_task<int(int)>’ is not derived from ‘const std::pair<_T1, _T2>’ } }; ^ In file included from /usr/include/c++/7/mutex:38:0, from /usr/include/c++/7/future:38, from test.cpp:2: /usr/include/c++/7/tuple:1031:19: note: candidate: template<class _U1, class _U2, typename std::enable_if<(_ConstructibleTuple<_U1, _U2>() && _ImplicitlyConvertibleTuple<_U1, _U2>()), bool>::type <anonymous> > constexpr std::tuple<_T1, _T2>::tuple(const std::pair<_U1, _U2>&) constexpr tuple(const pair<_U1, _U2>& __in) ^~~~~ /usr/include/c++/7/tuple:1031:19: note: template argument deduction/substitution failed: In file included from /usr/include/c++/7/future:39:0, from test.cpp:2: /usr/include/c++/7/thread:258:4: note:std::packaged_task<int(int)>’ is not derived from ‘const std::pair<_T1, _T2>’ } }; ^ In file included from /usr/include/c++/7/mutex:38:0, from /usr/include/c++/7/future:38, from test.cpp:2: /usr/include/c++/7/tuple:1022:28: note: candidate: template<class _U1, class _U2, typename std::enable_if<(_MoveConstructibleTuple<_U1, _U2>() && (! _ImplicitlyMoveConvertibleTuple<_U1, _U2>())), bool>::type <anonymous> > constexpr std::tuple<_T1, _T2>::tuple(std::tuple<_U1, _U2>&&) explicit constexpr tuple(tuple<_U1, _U2>&& __in) ^~~~~ /usr/include/c++/7/tuple:1022:28: note: template argument deduction/substitution failed: In file included from /usr/include/c++/7/future:39:0, from test.cpp:2: /usr/include/c++/7/thread:258:4: note:std::packaged_task<int(int)>’ is not derived from ‘std::tuple<_T1, _T2>’ } }; ^ In file included from /usr/include/c++/7/mutex:38:0, from /usr/include/c++/7/future:38, from test.cpp:2: /usr/include/c++/7/tuple:1013:19: note: candidate: template<class _U1, class _U2, typename std::enable_if<(_MoveConstructibleTuple<_U1, _U2>() && _ImplicitlyMoveConvertibleTuple<_U1, _U2>()), bool>::type <anonymous> > constexpr std::tuple<_T1, _T2>::tuple(std::tuple<_U1, _U2>&&) constexpr tuple(tuple<_U1, _U2>&& __in) ^~~~~ /usr/include/c++/7/tuple:1013:19: note: template argument deduction/substitution failed: In file included from /usr/include/c++/7/future:39:0, from test.cpp:2: /usr/include/c++/7/thread:258:4: note:std::packaged_task<int(int)>’ is not derived from ‘std::tuple<_T1, _T2>’ } }; ^ In file included from /usr/include/c++/7/mutex:38:0, from /usr/include/c++/7/future:38, from test.cpp:2: /usr/include/c++/7/tuple:1004:28: note: candidate: template<class _U1, class _U2, typename std::enable_if<(_ConstructibleTuple<_U1, _U2>() && (! _ImplicitlyConvertibleTuple<_U1, _U2>())), bool>::type <anonymous> > constexpr std::tuple<_T1, _T2>::tuple(const std::tuple<_U1, _U2>&) explicit constexpr tuple(const tuple<_U1, _U2>& __in) ^~~~~ /usr/include/c++/7/tuple:1004:28: note: template argument deduction/substitution failed: In file included from /usr/include/c++/7/future:39:0, from test.cpp:2: /usr/include/c++/7/thread:258:4: note:std::packaged_task<int(int)>’ is not derived from ‘const std::tuple<_T1, _T2>’ } }; ^ In file included from /usr/include/c++/7/mutex:38:0, from /usr/include/c++/7/future:38, from test.cpp:2: /usr/include/c++/7/tuple:995:19: note: candidate: template<class _U1, class _U2, typename std::enable_if<(_ConstructibleTuple<_U1, _U2>() && _ImplicitlyConvertibleTuple<_U1, _U2>()), bool>::type <anonymous> > constexpr std::tuple<_T1, _T2>::tuple(const std::tuple<_U1, _U2>&) constexpr tuple(const tuple<_U1, _U2>& __in) ^~~~~ /usr/include/c++/7/tuple:995:19: note: template argument deduction/substitution failed: In file included from /usr/include/c++/7/future:39:0, from test.cpp:2: /usr/include/c++/7/thread:258:4: note:std::packaged_task<int(int)>’ is not derived from ‘const std::tuple<_T1, _T2>’ } }; ^ In file included from /usr/include/c++/7/mutex:38:0, from /usr/include/c++/7/future:38, from test.cpp:2: /usr/include/c++/7/tuple:987:17: note: candidate: constexpr std::tuple<_T1, _T2>::tuple(std::tuple<_T1, _T2>&&) [with _T1 = std::packaged_task<int(int)>; _T2 = int] constexpr tuple(tuple&&) = default; ^~~~~ /usr/include/c++/7/tuple:987:17: note: candidate expects 1 argument, 2 provided /usr/include/c++/7/tuple:982:28: note: candidate: template<class _U1, class _U2, typename std::enable_if<((_MoveConstructibleTuple<_U1, _U2>() && (! _ImplicitlyMoveConvertibleTuple<_U1, _U2>())) && (! std::is_same<typename std::decay<_Tp>::type, std::allocator_arg_t>::value)), bool>::type <anonymous> > constexpr std::tuple<_T1, _T2>::tuple(_U1&&, _U2&&) explicit constexpr tuple(_U1&& __a1, _U2&& __a2) ^~~~~ /usr/include/c++/7/tuple:982:28: note: template argument deduction/substitution failed: /usr/include/c++/7/tuple:981:16: error: no type named ‘type’ in ‘struct std::enable_if<false, bool>’ bool>::type = false> ^~~~~ /usr/include/c++/7/tuple:981:16: note: invalid template non-type parameter /usr/include/c++/7/tuple:971:19: note: candidate: template<class _U1, class _U2, typename std::enable_if<((_MoveConstructibleTuple<_U1, _U2>() && _ImplicitlyMoveConvertibleTuple<_U1, _U2>()) && (! std::is_same<typename std::decay<_Tp>::type, std::allocator_arg_t>::value)), bool>::type <anonymous> > constexpr std::tuple<_T1, _T2>::tuple(_U1&&, _U2&&) constexpr tuple(_U1&& __a1, _U2&& __a2) ^~~~~ /usr/include/c++/7/tuple:971:19: note: template argument deduction/substitution failed: /usr/include/c++/7/tuple:970:16: error: no type named ‘type’ in ‘struct std::enable_if<false, bool>’ bool>::type = true> ^~~~ /usr/include/c++/7/tuple:970:16: note: invalid template non-type parameter /usr/include/c++/7/tuple:956:28: note: candidate: template<class _Dummy, typename std::enable_if<(std::_TC<std::is_same<_Dummy, void>::value, std::packaged_task<int(int)>, int>::_ConstructibleTuple<packaged_task<int(int)>, int>() && (! std::_TC<std::is_same<_Dummy, void>::value, std::packaged_task<int(int)>, int>::_ImplicitlyConvertibleTuple<packaged_task<int(int)>, int>())), bool>::type <anonymous> > constexpr std::tuple<_T1, _T2>::tuple(const _T1&, const _T2&) explicit constexpr tuple(const _T1& __a1, const _T2& __a2) ^~~~~ /usr/include/c++/7/tuple:956:28: note: template argument deduction/substitution failed: /usr/include/c++/7/tuple:955:16: error: no type named ‘type’ in ‘struct std::enable_if<false, bool>’ bool>::type = false> ^~~~~ /usr/include/c++/7/tuple:955:16: note: invalid template non-type parameter /usr/include/c++/7/tuple:947:19: note: candidate: template<class _Dummy, typename std::enable_if<(std::_TC<std::is_same<_Dummy, void>::value, std::packaged_task<int(int)>, int>::_ConstructibleTuple<packaged_task<int(int)>, int>() && std::_TC<std::is_same<_Dummy, void>::value, std::packaged_task<int(int)>, int>::_ImplicitlyConvertibleTuple<packaged_task<int(int)>, int>()), bool>::type <anonymous> > constexpr std::tuple<_T1, _T2>::tuple(const _T1&, const _T2&) constexpr tuple(const _T1& __a1, const _T2& __a2) ^~~~~ /usr/include/c++/7/tuple:947:19: note: template argument deduction/substitution failed: /usr/include/c++/7/tuple:946:16: error: no type named ‘type’ in ‘struct std::enable_if<false, bool>’ bool>::type = true> ^~~~ /usr/include/c++/7/tuple:946:16: note: invalid template non-type parameter /usr/include/c++/7/tuple:933:26: note: candidate: template<class _U1, class _U2, typename std::enable_if<std::__and_<std::is_default_constructible<_Tp>, std::is_default_constructible<_Dp>, std::__not_<std::__and_<std::__is_implicitly_default_constructible<_U1>, std::__is_implicitly_default_constructible<_U2> > > >::value, bool>::type <anonymous> > constexpr std::tuple<_T1, _T2>::tuple() explicit constexpr tuple() ^~~~~ /usr/include/c++/7/tuple:933:26: note: template argument deduction/substitution failed: In file included from /usr/include/c++/7/future:39:0, from test.cpp:2: /usr/include/c++/7/thread:258:4: note: candidate expects 0 arguments, 2 provided } }; ^ In file included from /usr/include/c++/7/mutex:38:0, from /usr/include/c++/7/future:38, from test.cpp:2: /usr/include/c++/7/tuple:919:17: note: candidate: template<class _U1, class _U2, typename std::enable_if<std::__and_<std::__is_implicitly_default_constructible<_U1>, std::__is_implicitly_default_constructible<_U2> >::value, bool>::type <anonymous> > constexpr std::tuple<_T1, _T2>::tuple() constexpr tuple() ^~~~~ /usr/include/c++/7/tuple:919:17: note: template argument deduction/substitution failed: In file included from /usr/include/c++/7/future:39:0, from test.cpp:2: /usr/include/c++/7/thread:258:4: note: candidate expects 0 arguments, 2 provided } }; ^ /usr/include/c++/7/thread:258:4: error: could not convert ‘{<expression error>}’ from ‘<brace-enclosed initializer list>’ to ‘std::thread::_Invoker<std::tuple<std::packaged_task<int(int)>, int> >’
最新发布
09-18
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值