简体   繁体   English

为什么std :: condition_variable作为类成员会导致std :: thread发生编译错误?

[英]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));

live example 现场例子

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM