スレッドを生成し、argsをスレッド関数に転送するこの単純な可変テンプレート関数を考えてみましょう。 スレッドコンストラクタでテンプレート置換エラーが発生するのはなぜですか?完全転送によるstd :: threadへの参照として可変長テンプレート引数を渡す
std::thread t;
void test3(int& a)
{
a = 10;
}
template<class ...Args>
void test(Args&&... args)
{
t = std::thread(test3, std::forward<Args>(args)...);
}
int main()
{
auto timer = 2s;
int a = 1;
test(a);
std::this_thread::sleep_for(timer);
std::cout << a << std::endl;
t.join();
}
コンパイラ出力:それは作品
std::thread(test3, std::ref(std::forward<Args>(args)...));
:
template argument deduction/substitution failed:
/opt/wandbox/gcc-head/include/c++/8.0.0/bits/invoke.h: In substitution of
'template<class _Callable, class ... _Args> constexpr typename
std::__invoke_result<_Functor, _ArgTypes>::type std::__invoke(_Callable&&,
_Args&& ...) [with _Callable = void (*)(int&); _Args = {int}]':
/opt/wandbox/gcc-head/include/c++/8.0.0/thread:233:29: required by
substitution of 'template<long unsigned int ..._Ind> decltype
(std::__invoke(_S_declval<_Ind>()...)) std::thread::_Invoker<std::tuple<void
(*)(int&), int> >::_M_invoke<_Ind ...>(std::_Index_tuple<_Ind1 ...>) [with
long unsigned int ..._Ind = {0, 1}]'
/opt/wandbox/gcc-head/include/c++/8.0.0/thread:240:2: required from
'struct std::thread::_Invoker<std::tuple<void (*)(int&), int> >'
/opt/wandbox/gcc-head/include/c++/8.0.0/thread:127:22: required from
'std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)
(int&); _Args = {int&}]'
prog.cc:23:14: required from 'void test(Args&& ...) [with Args = {int&}]'
prog.cc:43:11: required from here
/opt/wandbox/gcc-head/include/c++/8.0.0/bits/invoke.h:89:5: error: no type
named 'type' in 'struct std::__invoke_result<void (*)(int&), int>'
私はこのようなのstd :: refを持つ引数の転送を包む
。第一に完全に引き渡された議論ではないか?
['thread'のコンストラクタ](http://en.cppreference.com/w/cpp/thread/thread/thread)は、decay_copyの観点から定義されています。 – ildjarn
ildjarnが何を示唆しているかを詳しく調べるには、渡された関数が参照された整数のコピーと共に呼び出されます。そのコピーは期限切れの値です。非const左辺参照にバインドすることはできません。 – StoryTeller
@StoryTellerは、argsに対してstd :: refを使用する唯一の解決策ですか? – Mozbi