在另一个线程中调用类成员函数时的警告消息

Posted

技术标签:

【中文标题】在另一个线程中调用类成员函数时的警告消息【英文标题】:warning message when calling a class member function inside another as a thread 【发布时间】:2020-10-03 09:58:50 【问题描述】:

我有一个类,它包含多个方法。我的要求是将另一个成员函数中的一个作为线程调用。

Class ApplicationManager

   ....
   ....
   void method();
   void test(std::string arg1, std::string& arg2);
;

void ApplicationManager::method()

   std::string arg, arg2;
   ....
   ....
   std::thread(&ApplicationManager::test, this, arg, arg2);

当我编译上述内容时,我收到以下警告消息。由于它太大,我无法理解它试图表达的意思。已复制以下警告消息。

C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.16.27023\include\type_traits(16707566):警告 C4239:使用了非标准扩展:“参数” : 从 '_Ty' 到 'std::string &' 的转换 和 [ _Ty=std::basic_string,std::allocator> ] C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.16.27023\include\type_traits(16707566):注意:非常量引用只能绑定到左值 C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.16.27023\include\type_traits(16707566):注意:参见对函数模板实例化的参考 'void std::_Invoker_pmf_pointer:: _Call<_ty>,std::basic_string,std::allocator>,std::basic_string,std::allocator>>(_Decayed,_Ty1 &&,std::basic_string,std::allocator> &&, std::basic_string,std::allocator> &&) noexcept(false)' 正在编译 和 [ _Ty=void (__cdecl ApplicationManager::* )(std::string,std::string &), _Decayed=void (__cdecl ApplicationManager::* )(std::string,std::string &), _Ty1=应用程序管理器 * ]

C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.16.27023\include\thr/xthread(237): 注意:参见对函数模板实例化的参考 'void std::invoke,std::allocator>,std::basic_string,std::allocator>>(_Callable &&,应用程序管理器 &&,std::basic_string,std::allocator> &&,std::basic_string,std::allocator> &&) noexcept(false)' 正在编译 和 [ _Callable=void (__cdecl ApplicationManager:: )(std::string,std::string &) ] C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.16.27023\include\thr/xthread(246): 注意:参见对函数模板实例化的参考 'void std::_LaunchPad<_target>::_Execute(std::tuple,std::allocator>,std::basic_string,std::allocator>> &,std::integer_sequence<_ty>)' 正在编译 和 [ _Target=std::unique_ptr,std::allocator>,std::basic_string,std::allocator>>,std::default_delete,std::allocator>,std::basic_string,std::allocator>>>>, _Ty=size_t ] C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.16.27023\include\thr/xthread(245): 注意:参见对函数模板实例化的参考 'void std::_LaunchPad<_target>::_Execute(std::tuple,std::allocator>,std::basic_string,std::allocator>> &,std::integer_sequence<_ty>)' 正在编译 和 [ _Target=std::unique_ptr,std::allocator>,std::basic_string,std::allocator>>,std::default_delete,std::allocator>,std::basic_string,std::allocator>>>>, _Ty=size_t ] C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.16.27023\include\thr/xthread(242): 注意:在编译类模板成员函数'void std::_LaunchPad<_target>::_Run(std::_LaunchPad<_target> *) noexcept' 和 [ _Target=std::unique_ptr,std::allocator>,std::basic_string,std::allocator>>,std::default_delete,std::allocator>,std::basic_string,std::allocator>>>> ] C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.16.27023\include\thr/xthread(230): 注意:参见对函数模板实例化的参考 'void std::_LaunchPad<_target>::_Run(std::_LaunchPad<_target> *) noexcept' 正在编译 和 [ _Target=std::unique_ptr,std::allocator>,std::basic_string,std::allocator>>,std::default_delete,std::allocator>,std::basic_string,std::allocator>>>> ] C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.16.27023\include\thr/xthread(257): 注意:参见类模板实例化的参考 'std::_LaunchPad<_target>' 正在编译 和 [ _Target=std::unique_ptr,std::allocator>,std::basic_string,std::allocator>>,std::default_delete,std::allocator>,std::basic_string,std::allocator>>>> ] C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.16.27023\include\thread(46): 注意:参见对函数模板实例化的参考 'void std::_Launch,std::allocator>,std::basic_string,std::allocator>>,std::default_delete<_ty>>>(_Thrd_t *,_Target &&)' 正在编译 和 [ _Ty=std::tuple,std::allocator>,std::basic_string,std::allocator>>, _Target=std::unique_ptr,std::allocator>,std::basic_string,std::allocator>>,std::default_delete,std::allocator>,std::basic_string,std::allocator>>>> ] ....\Sources\ApplicationManager.cpp(3856):注意:参见函数模板实例化的参考 'std::thread::thread(_Fn &&,ApplicationManager &&,std::string &,std::string &)' 正在编译 和 [ _Fn=void (__cdecl ApplicationManager:: )(std::string,std::string &) ] C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.16.27023\include\filesystem(2392): 注意:参见类模板实例化的参考 'std::chrono::time_point' 正在编译 C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.16.27023\include\type_traits(616): 注意:参见类模板实例化的参考 'std::basic_string_view>' 是 编译 C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.16.27023\include\xstring(2124): 注意:参见类模板实例化的参考 'std::is_convertible>>' 是 编译 和 [ _StringViewIsh=const wchar_t * ] C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.16.27023\include\xstring(2122): 注意:参见变量模板 'const bool connector_v > >,std::negation > >' 正在编译 C:\Program Files (x86)\微软视觉 Studio\2017\Professional\VC\Tools\MSVC\14.16.27023\include\xstring(2281): 注意:参见别名模板实例化的参考 'std::basic_string,std::allocator>::_Is_string_view_ish<_stringviewish>' 正在编译 和 [ _StringViewIsh=const wchar_t * ]*

【问题讨论】:

无法复制:godbolt.org/z/kK7Mth 请编辑您的帖子以包含minimal reproducible example。 @aschepler 我编辑了我的帖子。我的第二个论点是参考。 @cigien 你能准确指出我的问题吗:( 这似乎是一个 msvc 扩展。当成员函数参数是左值引用时,gcc 和 clang 甚至不编译 this。 【参考方案1】:

你的功能

test(std::string arg1, std::string& arg2);

将引用作为第二个参数,但在这里

std::thread(&ApplicationManager::test, this, arg, arg2);

它需要一个值而不是引用,因此您必须将其修改为

std::thread(&ApplicationManager::test, this, arg, std::ref(arg2));

在引用包装对象中包装对变量的引用。 see

请注意,您发布的编译器消息是特定于 MVC 编译器的,但您的代码不会像 cigien 提到的那样使用 gcc 或 clang 编译(在编辑之前)。

【讨论】:

以上是关于在另一个线程中调用类成员函数时的警告消息的主要内容,如果未能解决你的问题,请参考以下文章

在另一个类c ++中调用成员函数

试图在另一个类函数中使用成员类函数

在另一个成员函数中调用成员函数时,在“int”之前的预期主表达式

MFC中多线程中静态函数调用成员函数的问题

如何在线程中调用其他类的成员函数和变量

在VC中,多线程如何调用类得成员函数?