Почему std :: condition_variable как член класса вызывает ошибки компиляции с std :: thread? - PullRequest
0 голосов
/ 28 июня 2018

Я пытался включить std::condition_variable в качестве члена класса и получил много ошибок компиляции при передаче объекта этого класса в std::thread. Я вырезал весь другой код из моей настоящей программы, и в итоге получил минимальный код ниже. Удаление std::condition_variable не вызывает проблем. Я попытался «инициализировать» переменную в конструкторе, а также сделать ее inline, но ни одна из них не помогла.

#include <thread>
#include <condition_variable>

struct ThreadHandler {
    void operator()() { }

    std::condition_variable cond; 
};

int main() {
    ThreadHandler th1;
    std::thread t1(th1);
    t1.join(); 
}

Что я здесь не так делаю?

Ниже приведена ошибка компиляции, которую я получаю:

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))

Ответы [ 2 ]

0 голосов
/ 28 июня 2018

Вы передаете экземпляр ThreadHandler по значению std::thread, но, как указано в документации для std::condition_variable

Класс std :: condition_variable является StandardLayoutType. Это не CopyConstructible, MoveConstructible, CopyAssignable, MoveAssignable .

Акцент мой. Так что это делает struct ThreadHandler также не копируемой / подвижной. Возможное решение - передать его по ссылке:

std::thread t1(std::ref(th1));

живой пример

Примечание: вам не нужно указывать ThreadHandler, чтобы быть функтором, будет работать только общий метод:

struct ThreadHandler {
    void thread_func() { }

    std::condition_variable cond; 
};

int main() {
    ThreadHandler th1;
    std::thread t1(&ThreadHandler::thread_func, &th1);
    t1.join(); 
}

это не только решит вашу проблему (я передал адрес th1, поэтому не нужно копировать), но и сделает его более читабельным (имя метода явным) и гибким (вы можете использовать разные методы для разных потоков)

0 голосов
/ 28 июня 2018

Вы никогда не сможете просто скопировать объекты синхронизации. Это заблокировано? Разблокирована? В середине блокировки или разблокировки?

C ++ condition_variables не имеют конструкторов копирования, и для них не имеет смысла их иметь. Жаль, что сообщения об ошибках не более полезны.

...