[英]Why does std::condition_variable as a class member cause compile errors with std::thread?
I tried including std::condition_variable
as a class member, and got a lot of compilation errors when passing an object of this class to a std::thread
. 我尝试将
std::condition_variable
包含为类成员,并且在将此类的对象传递给std::thread
时遇到很多编译错误。 I cut down all the other code from my actual program, and ended up with the below minimal code. 我从实际程序中删除了所有其他代码,最后得到了以下最少的代码。 Removing the
std::condition_variable
causes no problems. 删除
std::condition_variable
不会导致任何问题。 I tried "initializing" the variable in the constructor, as well as making it inline
, but neither helped. 我尝试在构造函数中“初始化”变量,并使其
inline
,但均无济于事。
#include <thread>
#include <condition_variable>
struct ThreadHandler {
void operator()() { }
std::condition_variable cond;
};
int main() {
ThreadHandler th1;
std::thread t1(th1);
t1.join();
}
What am I doing wrong here? 我在这里做错了什么?
Below is the compilation error I get: 以下是我得到的编译错误:
In file included from main.cpp:1:
/usr/local/include/c++/8.1.0/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 = ThreadHandler&; _Args = {}; typename std::decay<_Tp>::type = ThreadHandler]’:
/usr/local/include/c++/8.1.0/thread:127:22: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = ThreadHandler&; _Args = {}]’
main.cpp:14:23: required from here
/usr/local/include/c++/8.1.0/thread:258:4: error: no matching function for call to ‘std::tuple<ThreadHandler>::tuple(<brace-enclosed initializer list>)’
} };
^
In file included from /usr/local/include/c++/8.1.0/bits/unique_ptr.h:37,
from /usr/local/include/c++/8.1.0/memory:80,
from /usr/local/include/c++/8.1.0/thread:39,
from main.cpp:1:
/usr/local/include/c++/8.1.0/tuple:828:11: note: candidate: ‘template<class _Alloc, class _Dummy, class ... _UElements, typename std::enable_if<((std::_TC<((1 == sizeof... (_UElements)) && (! std::is_same<std::tuple<ThreadHandler>, std::tuple<_Tail ...> >::value)), ThreadHandler>::_MoveConstructibleTuple<_UElements ...>() && (! std::_TC<((1 == sizeof... (_UElements)) && (! std::is_same<std::tuple<ThreadHandler>, std::tuple<_Tail ...> >::value)), ThreadHandler>::_ImplicitlyMoveConvertibleTuple<_UElements ...>())) && std::_TC<(std::is_same<_Dummy, void>::value && (1 == 1)), ThreadHandler>::_NonNestedTuple<tuple<_Tail ...>&&>()), bool>::type <anonymous> > std::tuple<_Elements>::tuple(std::allocator_arg_t, const _Alloc&, std::tuple<_Args2 ...>&&)’
explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
^~~~~
/usr/local/include/c++/8.1.0/tuple:828:11: note: template argument deduction/substitution failed:
In file included from main.cpp:1:
/usr/local/include/c++/8.1.0/thread:258:4: note: candidate expects 3 arguments, 1 provided
} };
^
In file included from /usr/local/include/c++/8.1.0/bits/unique_ptr.h:37,
from /usr/local/include/c++/8.1.0/memory:80,
from /usr/local/include/c++/8.1.0/thread:39,
from main.cpp:1:
/usr/local/include/c++/8.1.0/tuple:813:2: note: candidate: ‘template<class _Alloc, class _Dummy, class ... _UElements, typename std::enable_if<((std::_TC<((1 == sizeof... (_UElements)) && (! std::is_same<std::tuple<ThreadHandler>, std::tuple<_Tail ...> >::value)), ThreadHandler>::_MoveConstructibleTuple<_UElements ...>() && std::_TC<((1 == sizeof... (_UElements)) && (! std::is_same<std::tuple<ThreadHandler>, std::tuple<_Tail ...> >::value)), ThreadHandler>::_ImplicitlyMoveConvertibleTuple<_UElements ...>()) && std::_TC<(std::is_same<_Dummy, void>::value && (1 == 1)), ThreadHandler>::_NonNestedTuple<tuple<_Tail ...>&&>()), bool>::type <anonymous> > std::tuple<_Elements>::tuple(std::allocator_arg_t, const _Alloc&, std::tuple<_Args2 ...>&&)’
tuple(allocator_arg_t __tag, const _Alloc& __a,
^~~~~
/usr/local/include/c++/8.1.0/tuple:813:2: note: template argument deduction/substitution failed:
In file included from main.cpp:1:
/usr/local/include/c++/8.1.0/thread:258:4: note: candidate expects 3 arguments, 1 provided
} };
^
In file included from /usr/local/include/c++/8.1.0/bits/unique_ptr.h:37,
from /usr/local/include/c++/8.1.0/memory:80,
from /usr/local/include/c++/8.1.0/thread:39,
from main.cpp:1:
/usr/local/include/c++/8.1.0/tuple:798:11: note: candidate: ‘template<class _Alloc, class _Dummy, class ... _UElements, typename std::enable_if<((std::_TC<((1 == sizeof... (_UElements)) && (! std::is_same<std::tuple<ThreadHandler>, std::tuple<_Tail ...> >::value)), ThreadHandler>::_ConstructibleTuple<_UElements ...>() && (! std::_TC<((1 == sizeof... (_UElements)) && (! std::is_same<std::tuple<ThreadHandler>, std::tuple<_Tail ...> >::value)), ThreadHandler>::_ImplicitlyConvertibleTuple<_UElements ...>())) && std::_TC<(std::is_same<_Dummy, void>::value && (1 == 1)), ThreadHandler>::_NonNestedTuple<tuple<_Tail ...>&&>()), bool>::type <anonymous> > std::tuple<_Elements>::tuple(std::allocator_arg_t, const _Alloc&, const std::tuple<_Args2 ...>&)’
explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
^~~~~
/usr/local/include/c++/8.1.0/tuple:798:11: note: template argument deduction/substitution failed:
In file included from main.cpp:1:
/usr/local/include/c++/8.1.0/thread:258:4: note: candidate expects 3 arguments, 1 provided
} };
^
In file included from /usr/local/include/c++/8.1.0/bits/unique_ptr.h:37,
from /usr/local/include/c++/8.1.0/memory:80,
from /usr/local/include/c++/8.1.0/thread:39,
from main.cpp:1:
/usr/local/include/c++/8.1.0/tuple:783:2: note: candidate: ‘template<class _Alloc, class _Dummy, class ... _UElements, typename std::enable_if<((std::_TC<((1 == sizeof... (_UElements)) && (! std::is_same<std::tuple<ThreadHandler>, std::tuple<_Tail ...> >::value)), ThreadHandler>::_ConstructibleTuple<_UElements ...>() && std::_TC<((1 == sizeof... (_UElements)) && (! std::is_same<std::tuple<ThreadHandler>, std::tuple<_Tail ...> >::value)), ThreadHandler>::_ImplicitlyConvertibleTuple<_UElements ...>()) && std::_TC<(std::is_same<_Dummy, void>::value && (1 == 1)), ThreadHandler>::_NonNestedTuple<tuple<_Tail ...>&&>()), bool>::type <anonymous> > std::tuple<_Elements>::tuple(std::allocator_arg_t, const _Alloc&, const std::tuple<_Args2 ...>&)’
tuple(allocator_arg_t __tag, const _Alloc& __a,
^~~~~
/usr/local/include/c++/8.1.0/tuple:783:2: note: template argument deduction/substitution failed:
In file included from main.cpp:1:
/usr/local/include/c++/8.1.0/thread:258:4: note: candidate expects 3 arguments, 1 provided
} };
^
In file included from /usr/local/include/c++/8.1.0/bits/unique_ptr.h:37,
from /usr/local/include/c++/8.1.0/memory:80,
from /usr/local/include/c++/8.1.0/thread:39,
from main.cpp:1:
/usr/local/include/c++/8.1.0/tuple:771:2: note: candidate: ‘template<class _Alloc> std::tuple<_Elements>::tuple(std::allocator_arg_t, const _Alloc&, std::tuple<_Elements>&&)’
tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
^~~~~
/usr/local/include/c++/8.1.0/tuple:771:2: note: template argument deduction/substitution failed:
In file included from main.cpp:1:
/usr/local/include/c++/8.1.0/thread:258:4: note: candidate expects 3 arguments, 1 provided
} };
^
In file included from /usr/local/include/c++/8.1.0/bits/unique_ptr.h:37,
from /usr/local/include/c++/8.1.0/memory:80,
from /usr/local/include/c++/8.1.0/thread:39,
from main.cpp:1:
/usr/local/include/c++/8.1.0/tuple:767:2: note: candidate: ‘template<class _Alloc> std::tuple<_Elements>::tuple(std::allocator_arg_t, const _Alloc&, const std::tuple<_Elements>&)’
tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
^~~~~
/usr/local/include/c++/8.1.0/tuple:767:2: note: template argument deduction/substitution failed:
In file included from main.cpp:1:
/usr/local/include/c++/8.1.0/thread:258:4: note: candidate expects 3 arguments, 1 provided
} };
^
In file included from /usr/local/include/c++/8.1.0/bits/unique_ptr.h:37,
from /usr/local/include/c++/8.1.0/memory:80,
from /usr/local/include/c++/8.1.0/thread:39,
from main.cpp:1:
/usr/local/include/c++/8.1.0/tuple:761:11: note: candidate: ‘template<class _Alloc, class ... _UElements, typename std::enable_if<(std::_TC<((1 == sizeof... (_UElements)) && std::_TC<(sizeof... (_UElements) == 1), ThreadHandler>::_NotSameTuple<_UElements ...>()), ThreadHandler>::_MoveConstructibleTuple<_UElements ...>() && (! std::_TC<((1 == sizeof... (_UElements)) && std::_TC<(sizeof... (_UElements) == 1), ThreadHandler>::_NotSameTuple<_UElements ...>()), ThreadHandler>::_ImplicitlyMoveConvertibleTuple<_UElements ...>())), bool>::type <anonymous> > std::tuple<_Elements>::tuple(std::allocator_arg_t, const _Alloc&, _UElements&& ...)’
explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
^~~~~
/usr/local/include/c++/8.1.0/tuple:761:11: note: template argument deduction/substitution failed:
In file included from main.cpp:1:
/usr/local/include/c++/8.1.0/thread:258:4: note: candidate expects at least 2 arguments, 1 provided
} };
^
In file included from /usr/local/include/c++/8.1.0/bits/unique_ptr.h:37,
from /usr/local/include/c++/8.1.0/memory:80,
from /usr/local/include/c++/8.1.0/thread:39,
from main.cpp:1:
/usr/local/include/c++/8.1.0/tuple:750:2: note: candidate: ‘template<class _Alloc, class ... _UElements, typename std::enable_if<(std::_TC<((1 == sizeof... (_UElements)) && std::_TC<(sizeof... (_UElements) == 1), ThreadHandler>::_NotSameTuple<_UElements ...>()), ThreadHandler>::_MoveConstructibleTuple<_UElements ...>() && std::_TC<((1 == sizeof... (_UElements)) && std::_TC<(sizeof... (_UElements) == 1), ThreadHandler>::_NotSameTuple<_UElements ...>()), ThreadHandler>::_ImplicitlyMoveConvertibleTuple<_UElements ...>()), bool>::type <anonymous> > std::tuple<_Elements>::tuple(std::allocator_arg_t, const _Alloc&, _UElements&& ...)’
tuple(allocator_arg_t __tag, const _Alloc& __a,
^~~~~
/usr/local/include/c++/8.1.0/tuple:750:2: note: template argument deduction/substitution failed:
In file included from main.cpp:1:
/usr/local/include/c++/8.1.0/thread:258:4: note: candidate expects at least 2 arguments, 1 provided
} };
^
In file included from /usr/local/include/c++/8.1.0/bits/unique_ptr.h:37,
from /usr/local/include/c++/8.1.0/memory:80,
from /usr/local/include/c++/8.1.0/thread:39,
from main.cpp:1:
/usr/local/include/c++/8.1.0/tuple:740:11: note: candidate: ‘template<class _Alloc, class _Dummy, typename std::enable_if<(std::_TC<std::is_same<_Dummy, void>::value, ThreadHandler>::_ConstructibleTuple<ThreadHandler>() && (! std::_TC<std::is_same<_Dummy, void>::value, ThreadHandler>::_ImplicitlyConvertibleTuple<ThreadHandler>())), bool>::type <anonymous> > std::tuple<_Elements>::tuple(std::allocator_arg_t, const _Alloc&, const _Elements& ...)’
explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
^~~~~
/usr/local/include/c++/8.1.0/tuple:740:11: note: template argument deduction/substitution failed:
In file included from main.cpp:1:
/usr/local/include/c++/8.1.0/thread:258:4: note: candidate expects 3 arguments, 1 provided
} };
^
In file included from /usr/local/include/c++/8.1.0/bits/unique_ptr.h:37,
from /usr/local/include/c++/8.1.0/memory:80,
from /usr/local/include/c++/8.1.0/thread:39,
from main.cpp:1:
/usr/local/include/c++/8.1.0/tuple:729:2: note: candidate: ‘template<class _Alloc, class _Dummy, typename std::enable_if<(std::_TC<std::is_same<_Dummy, void>::value, ThreadHandler>::_ConstructibleTuple<ThreadHandler>() && std::_TC<std::is_same<_Dummy, void>::value, ThreadHandler>::_ImplicitlyConvertibleTuple<ThreadHandler>()), bool>::type <anonymous> > std::tuple<_Elements>::tuple(std::allocator_arg_t, const _Alloc&, const _Elements& ...)’
tuple(allocator_arg_t __tag, const _Alloc& __a,
^~~~~
/usr/local/include/c++/8.1.0/tuple:729:2: note: template argument deduction/substitution failed:
In file included from main.cpp:1:
/usr/local/include/c++/8.1.0/thread:258:4: note: candidate expects 3 arguments, 1 provided
} };
^
In file included from /usr/local/include/c++/8.1.0/bits/unique_ptr.h:37,
from /usr/local/include/c++/8.1.0/memory:80,
from /usr/local/include/c++/8.1.0/thread:39,
from main.cpp:1:
/usr/local/include/c++/8.1.0/tuple:719:2: note: candidate: ‘template<class _Alloc> std::tuple<_Elements>::tuple(std::allocator_arg_t, const _Alloc&)’
tuple(allocator_arg_t __tag, const _Alloc& __a)
^~~~~
/usr/local/include/c++/8.1.0/tuple:719:2: note: template argument deduction/substitution failed:
In file included from main.cpp:1:
/usr/local/include/c++/8.1.0/thread:258:4: note: candidate expects 2 arguments, 1 provided
} };
^
In file included from /usr/local/include/c++/8.1.0/bits/unique_ptr.h:37,
from /usr/local/include/c++/8.1.0/memory:80,
from /usr/local/include/c++/8.1.0/thread:39,
from main.cpp:1:
/usr/local/include/c++/8.1.0/tuple:713:28: note: candidate: ‘template<class ... _UElements, class _Dummy, typename std::enable_if<((std::_TC<((1 == sizeof... (_UElements)) && (! std::is_same<std::tuple<ThreadHandler>, std::tuple<_Tps ...> >::value)), ThreadHandler>::_MoveConstructibleTuple<_UElements ...>() && (! std::_TC<((1 == sizeof... (_UElements)) && (! std::is_same<std::tuple<ThreadHandler>, std::tuple<_Tps ...> >::value)), ThreadHandler>::_ImplicitlyMoveConvertibleTuple<_UElements ...>())) && std::_TC<(std::is_same<_Dummy, void>::value && (1 == 1)), ThreadHandler>::_NonNestedTuple<tuple<_Tps ...>&&>()), bool>::type <anonymous> > constexpr std::tuple<_Elements>::tuple(std::tuple<_Args1 ...>&&)’
explicit constexpr tuple(tuple<_UElements...>&& __in)
^~~~~
/usr/local/include/c++/8.1.0/tuple:713:28: note: template argument deduction/substitution failed:
In file included from main.cpp:1:
/usr/local/include/c++/8.1.0/thread:258:4: note: ‘ThreadHandler’ is not derived from ‘std::tuple<_Tps ...>’
} };
^
In file included from /usr/local/include/c++/8.1.0/bits/unique_ptr.h:37,
from /usr/local/include/c++/8.1.0/memory:80,
from /usr/local/include/c++/8.1.0/thread:39,
from main.cpp:1:
/usr/local/include/c++/8.1.0/tuple:702:19: note: candidate: ‘template<class ... _UElements, class _Dummy, typename std::enable_if<((std::_TC<((1 == sizeof... (_UElements)) && (! std::is_same<std::tuple<ThreadHandler>, std::tuple<_Tps ...> >::value)), ThreadHandler>::_MoveConstructibleTuple<_UElements ...>() && std::_TC<((1 == sizeof... (_UElements)) && (! std::is_same<std::tuple<ThreadHandler>, std::tuple<_Tps ...> >::value)), ThreadHandler>::_ImplicitlyMoveConvertibleTuple<_UElements ...>()) && std::_TC<(std::is_same<_Dummy, void>::value && (1 == 1)), ThreadHandler>::_NonNestedTuple<tuple<_Tps ...>&&>()), bool>::type <anonymous> > constexpr std::tuple<_Elements>::tuple(std::tuple<_Args1 ...>&&)’
constexpr tuple(tuple<_UElements...>&& __in)
^~~~~
/usr/local/include/c++/8.1.0/tuple:702:19: note: template argument deduction/substitution failed:
In file included from main.cpp:1:
/usr/local/include/c++/8.1.0/thread:258:4: note: ‘ThreadHandler’ is not derived from ‘std::tuple<_Tps ...>’
} };
^
In file included from /usr/local/include/c++/8.1.0/bits/unique_ptr.h:37,
from /usr/local/include/c++/8.1.0/memory:80,
from /usr/local/include/c++/8.1.0/thread:39,
from main.cpp:1:
/usr/local/include/c++/8.1.0/tuple:690:28: note: candidate: ‘template<class ... _UElements, class _Dummy, typename std::enable_if<((std::_TC<((1 == sizeof... (_UElements)) && (! std::is_same<std::tuple<ThreadHandler>, std::tuple<_Tps ...> >::value)), ThreadHandler>::_ConstructibleTuple<_UElements ...>() && (! std::_TC<((1 == sizeof... (_UElements)) && (! std::is_same<std::tuple<ThreadHandler>, std::tuple<_Tps ...> >::value)), ThreadHandler>::_ImplicitlyConvertibleTuple<_UElements ...>())) && std::_TC<(std::is_same<_Dummy, void>::value && (1 == 1)), ThreadHandler>::_NonNestedTuple<const tuple<_Tps ...>&>()), bool>::type <anonymous> > constexpr std::tuple<_Elements>::tuple(const std::tuple<_Args1 ...>&)’
explicit constexpr tuple(const tuple<_UElements...>& __in)
^~~~~
/usr/local/include/c++/8.1.0/tuple:690:28: note: template argument deduction/substitution failed:
In file included from main.cpp:1:
/usr/local/include/c++/8.1.0/thread:258:4: note: ‘ThreadHandler’ is not derived from ‘const std::tuple<_Tps ...>’
} };
^
In file included from /usr/local/include/c++/8.1.0/bits/unique_ptr.h:37,
from /usr/local/include/c++/8.1.0/memory:80,
from /usr/local/include/c++/8.1.0/thread:39,
from main.cpp:1:
/usr/local/include/c++/8.1.0/tuple:678:19: note: candidate: ‘template<class ... _UElements, class _Dummy, typename std::enable_if<((std::_TC<((1 == sizeof... (_UElements)) && (! std::is_same<std::tuple<ThreadHandler>, std::tuple<_Tps ...> >::value)), ThreadHandler>::_ConstructibleTuple<_UElements ...>() && std::_TC<((1 == sizeof... (_UElements)) && (! std::is_same<std::tuple<ThreadHandler>, std::tuple<_Tps ...> >::value)), ThreadHandler>::_ImplicitlyConvertibleTuple<_UElements ...>()) && std::_TC<(std::is_same<_Dummy, void>::value && (1 == 1)), ThreadHandler>::_NonNestedTuple<const tuple<_Tps ...>&>()), bool>::type <anonymous> > constexpr std::tuple<_Elements>::tuple(const std::tuple<_Args1 ...>&)’
constexpr tuple(const tuple<_UElements...>& __in)
^~~~~
/usr/local/include/c++/8.1.0/tuple:678:19: note: template argument deduction/substitution failed:
In file included from main.cpp:1:
/usr/local/include/c++/8.1.0/thread:258:4: note: ‘ThreadHandler’ is not derived from ‘const std::tuple<_Tps ...>’
} };
^
In file included from /usr/local/include/c++/8.1.0/bits/unique_ptr.h:37,
from /usr/local/include/c++/8.1.0/memory:80,
from /usr/local/include/c++/8.1.0/thread:39,
from main.cpp:1:
/usr/local/include/c++/8.1.0/tuple:662:17: note: candidate: ‘constexpr std::tuple<_Elements>::tuple(std::tuple<_Elements>&&) [with _Elements = {ThreadHandler}]’
constexpr tuple(tuple&&) = default;
^~~~~
/usr/local/include/c++/8.1.0/tuple:662:17: note: no known conversion for argument 1 from ‘ThreadHandler’ to ‘std::tuple<ThreadHandler>&&’
/usr/local/include/c++/8.1.0/tuple:657:28: note: candidate: ‘template<class ... _UElements, typename std::enable_if<((std::_TC<((1 == sizeof... (_UElements)) && std::_TC<(sizeof... (_UElements) == 1), ThreadHandler>::_NotSameTuple<_UElements ...>()), ThreadHandler>::_MoveConstructibleTuple<_UElements ...>() && (! std::_TC<((1 == sizeof... (_UElements)) && std::_TC<(sizeof... (_UElements) == 1), ThreadHandler>::_NotSameTuple<_UElements ...>()), ThreadHandler>::_ImplicitlyMoveConvertibleTuple<_UElements ...>())) && (1 >= 1)), bool>::type <anonymous> > constexpr std::tuple<_Elements>::tuple(_UElements&& ...)’
explicit constexpr tuple(_UElements&&... __elements)
^~~~~
/usr/local/include/c++/8.1.0/tuple:657:28: note: template argument deduction/substitution failed:
/usr/local/include/c++/8.1.0/tuple:656:21: error: no type named ‘type’ in ‘struct std::enable_if<false, bool>’
bool>::type=false>
^~~~~
/usr/local/include/c++/8.1.0/tuple:646:19: note: candidate: ‘template<class ... _UElements, typename std::enable_if<((std::_TC<((1 == sizeof... (_UElements)) && std::_TC<(sizeof... (_UElements) == 1), ThreadHandler>::_NotSameTuple<_UElements ...>()), ThreadHandler>::_MoveConstructibleTuple<_UElements ...>() && std::_TC<((1 == sizeof... (_UElements)) && std::_TC<(sizeof... (_UElements) == 1), ThreadHandler>::_NotSameTuple<_UElements ...>()), ThreadHandler>::_ImplicitlyMoveConvertibleTuple<_UElements ...>()) && (1 >= 1)), bool>::type <anonymous> > constexpr std::tuple<_Elements>::tuple(_UElements&& ...)’
constexpr tuple(_UElements&&... __elements)
^~~~~
/usr/local/include/c++/8.1.0/tuple:646:19: note: template argument deduction/substitution failed:
/usr/local/include/c++/8.1.0/tuple:645:21: error: no type named ‘type’ in ‘struct std::enable_if<false, bool>’
bool>::type=true>
^~~~
/usr/local/include/c++/8.1.0/tuple:619:26: note: candidate: ‘template<class _Dummy, typename std::enable_if<((std::_TC<std::is_same<_Dummy, void>::value, ThreadHandler>::_ConstructibleTuple<ThreadHandler>() && (! std::_TC<std::is_same<_Dummy, void>::value, ThreadHandler>::_ImplicitlyConvertibleTuple<ThreadHandler>())) && (1 >= 1)), bool>::type <anonymous> > constexpr std::tuple<_Elements>::tuple(const _Elements& ...)’
explicit constexpr tuple(const _Elements&... __elements)
^~~~~
/usr/local/include/c++/8.1.0/tuple:619:26: note: template argument deduction/substitution failed:
/usr/local/include/c++/8.1.0/tuple:618:28: error: no type named ‘type’ in ‘struct std::enable_if<false, bool>’
bool>::type=false>
^~~~~
/usr/local/include/c++/8.1.0/tuple:608:19: note: candidate: ‘template<class _Dummy, typename std::enable_if<((std::_TC<std::is_same<_Dummy, void>::value, ThreadHandler>::_ConstructibleTuple<ThreadHandler>() && std::_TC<std::is_same<_Dummy, void>::value, ThreadHandler>::_ImplicitlyConvertibleTuple<ThreadHandler>()) && (1 >= 1)), bool>::type <anonymous> > constexpr std::tuple<_Elements>::tuple(const _Elements& ...)’
constexpr tuple(const _Elements&... __elements)
^~~~~
/usr/local/include/c++/8.1.0/tuple:608:19: note: template argument deduction/substitution failed:
/usr/local/include/c++/8.1.0/tuple:607:28: error: no type named ‘type’ in ‘struct std::enable_if<false, bool>’
bool>::type=true>
^~~~
/usr/local/include/c++/8.1.0/tuple:591:26: note: candidate: ‘template<class _Dummy, typename std::enable_if<(std::tuple<ThreadHandler>::_TC2<_Dummy>::_DefaultConstructibleTuple() && (! std::tuple<ThreadHandler>::_TC2<_Dummy>::_ImplicitlyDefaultConstructibleTuple())), bool>::type <anonymous> > constexpr std::tuple<_Elements>::tuple()’
explicit constexpr tuple()
^~~~~
/usr/local/include/c++/8.1.0/tuple:591:26: note: template argument deduction/substitution failed:
In file included from main.cpp:1:
/usr/local/include/c++/8.1.0/thread:258:4: note: candidate expects 0 arguments, 1 provided
} };
^
In file included from /usr/local/include/c++/8.1.0/bits/unique_ptr.h:37,
from /usr/local/include/c++/8.1.0/memory:80,
from /usr/local/include/c++/8.1.0/thread:39,
from main.cpp:1:
/usr/local/include/c++/8.1.0/tuple:581:17: note: candidate: ‘template<class _Dummy, typename std::enable_if<std::tuple<ThreadHandler>::_TC2<_Dummy>::_ImplicitlyDefaultConstructibleTuple(), bool>::type <anonymous> > constexpr std::tuple<_Elements>::tuple()’
constexpr tuple()
^~~~~
/usr/local/include/c++/8.1.0/tuple:581:17: note: template argument deduction/substitution failed:
In file included from main.cpp:1:
/usr/local/include/c++/8.1.0/thread:258:4: note: candidate expects 0 arguments, 1 provided
} };
^
/usr/local/include/c++/8.1.0/thread:258:4: error: could not convert ‘{<expression error>}’ from ‘<brace-enclosed initializer list>’ to ‘std::thread::_Invoker<std::tuple<ThreadHandler> >’
In file included from /usr/local/include/c++/8.1.0/bits/unique_ptr.h:37,
from /usr/local/include/c++/8.1.0/memory:80,
from /usr/local/include/c++/8.1.0/thread:39,
from main.cpp:1:
/usr/local/include/c++/8.1.0/tuple: In instantiation of ‘constexpr std::_Head_base<_Idx, _Head, false>::_Head_base(_UHead&&) [with _UHead = ThreadHandler; long unsigned int _Idx = 0; _Head = ThreadHandler]’:
/usr/local/include/c++/8.1.0/tuple:373:49: required from ‘constexpr std::_Tuple_impl<_Idx, _Head>::_Tuple_impl(std::_Tuple_impl<_Idx, _Head>&&) [with long unsigned int _Idx = 0; _Head = ThreadHandler]’
/usr/local/include/c++/8.1.0/tuple:662:17: required from ‘std::thread::_State_impl<_Callable>::_State_impl(_Callable&&) [with _Callable = std::thread::_Invoker<std::tuple<ThreadHandler> >]’
/usr/local/include/c++/8.1.0/thread:197:20: required from ‘static std::thread::_State_ptr std::thread::_S_make_state(_Callable&&) [with _Callable = std::thread::_Invoker<std::tuple<ThreadHandler> >; std::thread::_State_ptr = std::unique_ptr<std::thread::_State>]’
/usr/local/include/c++/8.1.0/thread:126:38: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = ThreadHandler&; _Args = {}]’
main.cpp:14:23: required from here
/usr/local/include/c++/8.1.0/tuple:133:42: error: use of deleted function ‘ThreadHandler::ThreadHandler(ThreadHandler&&)’
: _M_head_impl(std::forward<_UHead>(__h)) { }
^
main.cpp:4:8: note: ‘ThreadHandler::ThreadHandler(ThreadHandler&&)’ is implicitly deleted because the default definition would be ill-formed:
struct ThreadHandler
^~~~~~~~~~~~~
main.cpp:4:8: error: use of deleted function ‘std::condition_variable::condition_variable(const std::condition_variable&)’
In file included from main.cpp:2:
/usr/local/include/c++/8.1.0/condition_variable:82:5: note: declared here
condition_variable(const condition_variable&) = delete;
^~~~~~~~~~~~~~~~~~
In file included from main.cpp:1:
/usr/local/include/c++/8.1.0/thread: In instantiation of ‘std::thread::_State_impl<_Callable>::_State_impl(_Callable&&) [with _Callable = std::thread::_Invoker<std::tuple<ThreadHandler> >]’:
/usr/local/include/c++/8.1.0/thread:197:20: required from ‘static std::thread::_State_ptr std::thread::_S_make_state(_Callable&&) [with _Callable = std::thread::_Invoker<std::tuple<ThreadHandler> >; std::thread::_State_ptr = std::unique_ptr<std::thread::_State>]’
/usr/local/include/c++/8.1.0/thread:126:38: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = ThreadHandler&; _Args = {}]’
main.cpp:14:23: required from here
/usr/local/include/c++/8.1.0/thread:221:14: note: synthesized method ‘constexpr std::tuple<_Elements>::tuple(std::tuple<_Elements>&&) [with _Elements = {ThreadHandler}]’ first required here
struct _Invoker
^~~~~~~~
/usr/local/include/c++/8.1.0/thread:182:69: note: synthesized method ‘constexpr std::thread::_Invoker<std::tuple<ThreadHandler> >::_Invoker(std::thread::_Invoker<std::tuple<ThreadHandler> >&&)’ first required here
_State_impl(_Callable&& __f) : _M_func(std::forward<_Callable>(__f))
You pass instance of ThreadHandler
by value to std::thread
but as stated in documentation for std::condition_variable
您按值将
ThreadHandler
的实例传递给std::thread
但如std::condition_variable
文档中所述
The class std::condition_variable is a StandardLayoutType.
类std :: condition_variable是StandardLayoutType。 It is not CopyConstructible, MoveConstructible, CopyAssignable, MoveAssignable .
它不是CopyConstructible,MoveConstructible,CopyAssignable,MoveAssignable 。
Emphasis is mine. 重点是我的。 So it makes struct
ThreadHandler
not copyable/movable either. 因此,它也使
ThreadHandler
不可复制/不可移动。 Possible solution is to pass it by reference: 可能的解决方案是通过引用传递它:
std::thread t1(std::ref(th1));
Note: you do not have to make ThreadHandler
to be a functor, just general method would work: 注意:您不必使
ThreadHandler
成为函子,只需常规方法即可:
struct ThreadHandler {
void thread_func() { }
std::condition_variable cond;
};
int main() {
ThreadHandler th1;
std::thread t1(&ThreadHandler::thread_func, &th1);
t1.join();
}
this not only would solve your issue (I passed address of th1
so no copy involved) but make it more readable (method name is explicit) and flexible (you can use different methods for different threads) 这不仅可以解决您的问题(我通过了
th1
地址,所以不涉及任何副本),但使其更具可读性(方法名是显式的)且灵活(可以为不同的线程使用不同的方法)
You can never just copy synchronization objects. 您永远不能只复制同步对象。 Is it locked?
它被锁定了吗? Unlocked?
解锁了吗? In the middle of locking or unlocking?
在锁定或解锁过程中?
C++ condition_variables don't have copy constructors and it doesn't make sense for them to have them. C ++ condition_variables没有复制构造函数,因此让他们拥有它们是没有意义的。 It is a shame the error messages aren't more useful though.
可惜的是,错误消息没有再有用了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.