Есть ли способ создать std::thread, используя объект и его оператор вызова непустого списка аргументов?
Я новичок в
std::thread
и C++11 в целом. Пытаясь поиграть с примерами из https://en.cppreference.com/w/cpp/thread/thread/thread, я пытаюсь проверить, смогу ли я создать
std::thread
используя оператор вызова функции-члена класса с непустым списком аргументов, как в приведенном ниже коде:
// main.cpp
#include <iostream>
#include <iostream>
#include <thread>
class Foo {
public:
void operator()( int& i ) {
std::cout << i << std::endl;
}
};
int main( int argc, char* argv[] ) {
Foo f;
int i = 42;
std::thread t1( f, i );
t1.join();
return 0;
}
Сообщение об ошибке загадочное:
$ g++ --version && g++ ./main.cpp -lpthread && ./a.out
g++ (Debian 6.3.0-18+deb9u1) 6.3.0 20170516
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
In file included from /usr/include/c++/6/thread:39:0,
from ./main.cpp:5:
/usr/include/c++/6/functional: In instantiation of ‘struct std::_Bind_simple<Foo(int)>’:
/usr/include/c++/6/thread:138:26: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = Foo&; _Args = {int&}]’
./main.cpp:19:24: required from here
/usr/include/c++/6/functional:1365:61: error: no type named ‘type’ in ‘class std::result_of<Foo(int)>’
typedef typename result_of<_Callable(_Args...)>::type result_type;
^~~~~~~~~~~
/usr/include/c++/6/functional:1386:9: error: no type named ‘type’ in ‘class std::result_of<Foo(int)>’
_M_invoke(_Index_tuple<_Indices...>)
Напротив, оператор вызова пустого списка аргументов работает нормально:
// main.cpp
#include <iostream>
#include <iostream>
#include <thread>
class Foo {
public:
void operator()() {
std::cout << 42 << std::endl;
}
};
int main( int argc, char* argv[] ) {
Foo f;
int i = 42;
std::thread t1( f );
t1.join();
return 0;
}
$ g++ --version && g++ ./main.cpp -lpthread && ./a.out
g++ (Debian 6.3.0-18+deb9u1) 6.3.0 20170516
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
42
Возможна ли моя первая попытка - у меня просто синтаксическая ошибка? Есть ли способ создать std::thread, используя объект и его оператор вызова непустого списка аргументов?
Я считаю, что этот вопрос отличается от Start thread with member function, потому что этот вопрос конкретно касается создания потока с использованием оператора вызова объекта-члена. Я знаю, что это можно сделать с помощью лямбда-выражений.
1 ответ
std::thread
не позволяет передавать по ссылке, если вы явно не указали, потому что это легкий источник проблем на протяжении всего срока службы. Использовать
std::ref
быть явным, что вы проходите
i
по ссылке:
std::thread t1( f, std::ref(i) );
Как вариант, переходите по значению. Хорошо подумайте, прежде чем передавать что-то в поток по ссылке, и убедитесь, что это необходимо. Переменная, которую вы передаете, должна пережить свое использование внутри потока.