无法在线程中专门化函数模板

时间:2015-09-24 15:35:25

标签: c++ multithreading

我正在尝试在c ++中实现一个Thread,它将用于控制我何时拍照,但是这个简单的代码给了我一个奇怪的错误,我无法理解。这是我的代码:

#include <iostream>
#include <fstream>
#include <thread>
    using namespace std;

    void counter(int seconds, bool &flagTakePhoto, bool &flagThreadStart);

int main() {
    bool takePhoto, threadStart;

    int seconds = 1;

    thread t(counter, seconds, takePhoto, threadStart);
    //Some code here
}


void counter(int seconds, bool &flagTakePhoto, bool &flagThreadStart) {
    while (flagThreadStart) {
        this_thread::sleep_for(chrono::seconds(seconds));
        flagTakePhoto = true;
    }
    terminate();
}

这是错误:

1>------ Build started: Project: Proyecto para pruebas OPENCV, Configuration: 
Release x64 ------
1>  Main.cpp
1>Main.cpp(46): warning C4244: 'initializing': conversion from '__int64' to 'int', possible loss of data
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 (__cdecl *)(int,bool &,bool &)'
1>  C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\thr/xthread(238): note: '_Types={int, bool, bool}'
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<0x00,0x01,0x02,0x03>(std::tuple<void (__cdecl *)(int,bool &,bool &),int,bool,bool> &,std::integer_sequence<_Ty,0x00,0x01,0x02,0x03>)' being compiled
1>          with
1>          [
1>              _Target=std::unique_ptr<std::tuple<void (__cdecl *)(int,bool &,bool &),int,bool,bool>,std::default_delete<std::tuple<void (__cdecl *)(int,bool &,bool &),int,bool,bool>>>,
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<0x00,0x01,0x02,0x03>(std::tuple<void (__cdecl *)(int,bool &,bool &),int,bool,bool> &,std::integer_sequence<_Ty,0x00,0x01,0x02,0x03>)' being compiled
1>          with
1>          [
1>              _Target=std::unique_ptr<std::tuple<void (__cdecl *)(int,bool &,bool &),int,bool,bool>,std::default_delete<std::tuple<void (__cdecl *)(int,bool &,bool &),int,bool,bool>>>,
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 (__cdecl *)(int,bool &,bool &),int,bool,bool>,std::default_delete<std::tuple<void (__cdecl *)(int,bool &,bool &),int,bool,bool>>>
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 (__cdecl *)(int,bool &,bool &),int,bool,bool>,std::default_delete<std::tuple<void (__cdecl *)(int,bool &,bool &),int,bool,bool>>>
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 (__cdecl *)(int,bool &,bool &),int,bool,bool>,std::default_delete<std::tuple<void (__cdecl *)(int,bool &,bool &),int,bool,bool>>>
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 (__cdecl *)(int,bool &,bool &),int,bool,bool>,std::default_delete<std::tuple<void (__cdecl *)(int,bool &,bool &),int,bool,bool>>>>(_Thrd_t *,_Target &&)' being compiled
1>          with
1>          [
1>              _Target=std::unique_ptr<std::tuple<void (__cdecl *)(int,bool &,bool &),int,bool,bool>,std::default_delete<std::tuple<void (__cdecl *)(int,bool &,bool &),int,bool,bool>>>
1>          ]
1>  Main.cpp(136): note: see reference to function template instantiation 'std::thread::thread<void(__cdecl &)(int,bool &,bool &),int&,bool&,bool&,void>(_Fn,int &,bool &,bool &)' being compiled
1>          with
1>          [
1>              _Fn=void (__cdecl &)(int,bool &,bool &)
1>          ]
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

更奇怪的是,我在其他程序中有类似的代码并且编译没有错误! 有谁知道这段代码有什么问题? 谢谢!

1 个答案:

答案 0 :(得分:2)

std::thread constructor将构造其所有对象,并通过以下方式调用该函数:

thread t(counter, seconds, takePhoto, threadStart);

这使得参数类型为

int

boolboolcounter(int, bool, bool)。由于您无法调用T&(它需要左值引用),因此该构造函数格式不正确。

为了传递引用,您需要将参数包装在std::reference_wrapper<T>中。该类型可隐式转换为counter(int, std::reference_wrapper<bool>, std::reference_wrapper<bool>),因此调用thread t(counter, seconds, std::ref(takePhoto), std::ref(threadStart)); 有效。简而言之,标准提供了std::ref,因此您可以执行以下操作:

{{1}}