Исходное сообщение (с ошибками)
Я хочу обернуть вызов конструктора std::thread (чтобы отслеживать все запущенные потоки, чтобы я мог присоединиться к ним или сделать что-то еще). В этом примере поток t1
создается правильно, но поток t2
не использует gcc 4.8.1. Однако в Windows (VS2012) он компилируется без ошибок и работает без ошибок. Основываясь на обсуждении здесь, это может кажется ошибкой в gcc, но, возможно, это ошибка в VS. Каков правильный способ сделать это?
#include <iostream>
#include <thread>
class A {
public:
void foo(int n ) { std::cout << n << std::endl; }
};
template<class F, class Arg>
std::thread& wrapper(F&& f, Arg&& a)
{
std::thread* t = new std::thread(f,a,100);
return *t;
}
int main()
{
A a;
std::thread t1(&A::foo, &a, 100);
t1.join();
std::thread t2 = wrapper(&A::foo, &a);
t2.join();
return 0;
}
Вот ошибка компилятора
-bash-4.1$ make
g++ -std=c++11 main.cpp -o main
main.cpp: In function ‘int main()’:
main.cpp:23:41: error: use of deleted function ‘std::thread::thread(std::thread&)’
std::thread t2 = wrapper(&A::foo, &a);
^
In file included from main.cpp:2:0:
/opt/rh/devtoolset-2/root/usr/include/c++/4.8.1/thread:125:5: error: declared here
thread(thread&) = delete;
^
make: *** [all] Error 1
Обновлять
Я задал здесь неправильный вопрос и собираюсь удалить его, но, поскольку ответы полезны, я оставлю его. Проблема заключалась в том, что компилятор Intel icpc 14.0 (не gcc 4.8.1) был выдает ту же ошибку относительно bind
, что обсуждалась здесь. И это не имеет ничего общего с «оболочкой», а просто вызывает std::thread с функцией-членом вместо статической функции.
Жалобы на утечку памяти верны на 100%, но это я неудачно упростил пример (из моего реального кода). Фактический код сохраняет потоки в контейнере и удаляет потоки при уничтожении.
Вот лучший пример:
#include <iostream>
#include <thread>
class A {
public:
void foo() { }
template<class Function, class Arg>
std::thread* wrapper(Function&& f, Arg&& a)
{
auto t = new std::thread(f,a);
return t;
}
};
int main()
{
A a;
std::thread t1(&A::foo, &a);
t1.join();
std::thread* t2 = a.wrapper(&A::foo, &a);
t2->join();
delete t2;
return 0;
}
И вывод для g++
(4.8.1) который работает
-bash-4.1$ make CXX=g++
g++ -lpthread -std=c++11 main.cpp -o main
и вывод для компилятора Intel icpc
(14.0), который не работает
-bash-4.1$ make CXX=icpc
icpc -lpthread -std=c++11 main.cpp -o main
/opt/rh/devtoolset-2/root/usr/include/c++/4.8.1/functional(1697): error: class "std::result_of<std::_Mem_fn<void (A::*)()> (A *)>" has no member "type"
typedef typename result_of<_Callable(_Args...)>::type result_type;
^
detected during:
instantiation of class "std::_Bind_simple<_Callable (_Args...)> [with _Callable=std::_Mem_fn<void (A::*)()>, _Args=<A *>]" at line 1753
instantiation of "std::_Bind_simple_helper<_Callable, _Args...>::__type std::__bind_simple(_Callable &&, _Args &&...) [with _Callable=void (A::*)(), _Args=<A *>]" at line 137 of "/opt/rh/devtoolset-2/root/usr/include/c++/4.8.1/thread"
instantiation of "std::thread::thread(_Callable &&, _Args &&...) [with _Callable=void (A::*)(), _Args=<A *>]" at line 20 of "main.cpp"
/opt/rh/devtoolset-2/root/usr/include/c++/4.8.1/functional(1726): error: class "std::result_of<std::_Mem_fn<void (A::*)()> (A *)>" has no member "type"
typename result_of<_Callable(_Args...)>::type
^
detected during:
instantiation of class "std::_Bind_simple<_Callable (_Args...)> [with _Callable=std::_Mem_fn<void (A::*)()>, _Args=<A *>]" at line 1753
instantiation of "std::_Bind_simple_helper<_Callable, _Args...>::__type std::__bind_simple(_Callable &&, _Args &&...) [with _Callable=void (A::*)(), _Args=<A *>]" at line 137 of "/opt/rh/devtoolset-2/root/usr/include/c++/4.8.1/thread"
instantiation of "std::thread::thread(_Callable &&, _Args &&...) [with _Callable=void (A::*)(), _Args=<A *>]" at line 20 of "main.cpp"
compilation aborted for main.cpp (code 2)
make: *** [all] Error 2
-bash-4.1$
new
для создания объекта потока, но не вызываетеdelete
для освобождения памяти. - person Alex Zywicki   schedule 08.05.2014std::ref
, тогда как ваш вопрос касается конструкторов копирования потоков. - person Mooing Duck   schedule 08.05.2014icpc
, как показано. - person Mark Lakata   schedule 08.05.2014