c++ - Visual C++ 14 - 无法构建基于 Visual C++ 12 的简单线程程序

标签 c++ visual-studio visual-c++ visual-studio-2015 visual-c++-2015

我有这个 MCVE

#include <iostream>
#include <thread>

class Foo
{
    void bar_i() { std::cout << "hello" << std::endl; }

public:
    void bar()
    {
        // I don't know why I used std::ref(*this) instead of this, I wrote this some time ago
        std::thread t(&Foo::bar_i, std::ref(*this));
        t.join();
    }
};

int main()
{
    Foo f;
    f.bar();
}

它基于 VS 2013 Update 3 和 Coliru , 但不建立在 VS 2015 上并带有此错误列表:

1>c:\program files (x86)\microsoft visual studio 14.0\vc\include\thr\xthread(238): error C2893: Failed to specialize function template 'unknown-type std::invoke(_Callable &&,_Types &&...)'
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\thr\xthread(238): note: With the following template arguments:
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\thr\xthread(238): note: '_Callable=void (__thiscall Foo::* )(void)'
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\thr\xthread(238): note: '_Types={std::reference_wrapper<Foo>}'
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\thr\xthread(247): note: see reference to function template instantiation 'void std::_LaunchPad<_Target>::_Execute<0,1>(std::tuple<void (__thiscall Foo::* )(void),std::reference_wrapper<Foo>> &,std::integer_sequence<_Ty,0,1>)' being compiled
1>          with
1>          [
1>              _Target=std::unique_ptr<std::tuple<void (__thiscall Foo::* )(void),std::reference_wrapper<Foo>>,std::default_delete<std::tuple<void (__thiscall Foo::* )(void),std::reference_wrapper<Foo>>>>,
1>              _Ty=size_t
1>          ]
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\thr\xthread(247): note: see reference to function template instantiation 'void std::_LaunchPad<_Target>::_Execute<0,1>(std::tuple<void (__thiscall Foo::* )(void),std::reference_wrapper<Foo>> &,std::integer_sequence<_Ty,0,1>)' being compiled
1>          with
1>          [
1>              _Target=std::unique_ptr<std::tuple<void (__thiscall Foo::* )(void),std::reference_wrapper<Foo>>,std::default_delete<std::tuple<void (__thiscall Foo::* )(void),std::reference_wrapper<Foo>>>>,
1>              _Ty=size_t
1>          ]
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\thr\xthread(242): note: while compiling class template member function 'void std::_LaunchPad<_Target>::_Run(std::_LaunchPad<_Target> *) noexcept'
1>          with
1>          [
1>              _Target=std::unique_ptr<std::tuple<void (__thiscall Foo::* )(void),std::reference_wrapper<Foo>>,std::default_delete<std::tuple<void (__thiscall Foo::* )(void),std::reference_wrapper<Foo>>>>
1>          ]
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\thr\xthread(230): note: see reference to function template instantiation 'void std::_LaunchPad<_Target>::_Run(std::_LaunchPad<_Target> *) noexcept' being compiled
1>          with
1>          [
1>              _Target=std::unique_ptr<std::tuple<void (__thiscall Foo::* )(void),std::reference_wrapper<Foo>>,std::default_delete<std::tuple<void (__thiscall Foo::* )(void),std::reference_wrapper<Foo>>>>
1>          ]
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\thr\xthread(256): note: see reference to class template instantiation 'std::_LaunchPad<_Target>' being compiled
1>          with
1>          [
1>              _Target=std::unique_ptr<std::tuple<void (__thiscall Foo::* )(void),std::reference_wrapper<Foo>>,std::default_delete<std::tuple<void (__thiscall Foo::* )(void),std::reference_wrapper<Foo>>>>
1>          ]
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\thread(52): note: see reference to function template instantiation 'void std::_Launch<std::unique_ptr<std::tuple<void (__thiscall Foo::* )(void),std::reference_wrapper<Foo>>,std::default_delete<std::tuple<void (__thiscall Foo::* )(void),std::reference_wrapper<Foo>>>>>(_Thrd_t *,_Target &&)' being compiled
1>          with
1>          [
1>              _Target=std::unique_ptr<std::tuple<void (__thiscall Foo::* )(void),std::reference_wrapper<Foo>>,std::default_delete<std::tuple<void (__thiscall Foo::* )(void),std::reference_wrapper<Foo>>>>
1>          ]
1>  d:\libraries\c++ active\tests\tests\test.cpp(13): note: see reference to function template instantiation 'std::thread::thread<void(__thiscall Foo::* )(void),std::reference_wrapper<Foo>,void>(_Fn &&,std::reference_wrapper<Foo> &&)' being compiled
1>          with
1>          [
1>              _Fn=void (__thiscall Foo::* )(void)
1>          ]

如果不是 std::ref,这段代码可以编译。似乎是什么问题?

最佳答案

据我所知,20.9.2 中的规则导致您的代码等同于

auto f = &Foo::bar_i;
decay<decltype(std::ref(*this))>::type t1 = std::ref(*this); // still reference_wrapper
((*t1).*f)();

这实际上是一个错误。

只需使用 std::thread t(&Foo::bar_i, this);,因为指向成员函数的机制存在于 std::thread 中知道在执行调用时取消引用第一个参数。

根据稿件n4527我在看,std::bind(参见 20.9.10.3)使用的 std::reference_wrapper 的特殊处理不适用于 std::线程std::tuple 使用的特殊衰减逻辑也不是,这导致 reference_wrapper 成为普通引用。

关于c++ - Visual C++ 14 - 无法构建基于 Visual C++ 12 的简单线程程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33044736/

相关文章:

c - 如何在内联汇编中声明字符缓冲区?

c++ - 在 C++ 中用正斜杠或双反斜杠替换反斜杠

c++ - 如何从 native win32 C++ 应用程序获取当前实例的可执行文件名?

C++ 不发出蜂鸣声

asp.net - Web 应用程序存在于本地 IIS Web 服务器和 IIS Express Web 服务器上

visual-studio - VSTS - 如何使用更改集注释?

c++ - 如何使用 winapi 创建一个对话框来选择多个文件?

c++ - 未为 QTableView 行调用 QStyledItemDelegate 的 sizeHint 方法

c++ - 将 GUI 添加到非托管/boost C++ 应用程序

visual-studio - 如何在 VC++ 项目中包含构建时间戳?