C++ 线程和承诺:试图引用已删除的函数

Posted

技术标签:

【中文标题】C++ 线程和承诺:试图引用已删除的函数【英文标题】:C++ Thread and Promise : attempting to reference a deleted function 【发布时间】:2016-05-18 12:20:41 【问题描述】:

我在运行这个我在网上找到的示例时遇到了一些问题。

void asyncFun(std::promise<int> intPromise) 
    int result=5;
    try 
        // calculate the result
        intPromise.set_value(result);
    
    catch (...) 
        intPromise.set_exception(std::current_exception());
     


int _tmain(int argc, _TCHAR* argv[]) 
    std::promise<int> intPromise;
    std::future<int> intFuture = intPromise.get_future();
    std::thread t(asyncFun, std::move(intPromise));
    std::cout << "Main thread" << std::endl;
    int result = intFuture.get(); // may throw MyException
    std::cout << result<<std::endl;
    return 0;

我得到了:

错误 C2280: 'std::promise::promise(const std::promise &)' : 试图引用已删除的 函数 c:\program files (x86)\microsoft visual studio 12.0\vc\include\functional 1149 1 尝试未来

【问题讨论】:

这是个bug,你用的是什么版本的VS? 使用 VS 2013,我现在正在安装 2015 好的,但是还有另一种解决方法,使用shared_ptr,请参阅我的答案。 【参考方案1】:

这是您正在使用的实现中的一个错误。如果可以,请考虑升级。

std::thread 的参数必须是MoveConstructiblestd::promise 满足这些要求。

它在http://webcompiler.cloudapp.net 在线编译并运行(在main 中添加了t.join())。作为一种变通方法,您可以考虑“提供”引用(使用std::ref 并从promise 移动),但要警告使用这种变通方法的悬空引用。

这里的另一个解决方法是使用 std::shared_ptrstd::promise 作为函数的参数。

void asyncFun(std::shared_ptr<std::promise<int>> intPromise) 
    int result=5;
    try 
        // calculate the result
        intPromise->set_value(result);
    
    catch (...) 
        intPromise->set_exception(std::current_exception());
     


int main() 
    std::promise<int> intPromise;
    std::future<int> intFuture = intPromise.get_future();
    auto sh = std::make_shared<std::promise<int>>(std::move(intPromise));
    std::thread t(asyncFun, sh);
    std::cout << "Main thread" << std::endl;
    int result = intFuture.get(); // may throw MyException
    std::cout << result<<std::endl;
    t.join();
    return 0;

【讨论】:

你说得对,我上面发布的代码是一个例子,我的代码有一个循环,所以我不能使用引用,否则当我退出循环时我会丢失它们 没问题,shared_ptr 替代方案将对此有所帮助。

以上是关于C++ 线程和承诺:试图引用已删除的函数的主要内容,如果未能解决你的问题,请参考以下文章

VS2019 C++ 错误 C2280 试图引用已删除的函数 inl

Visual Studio 2013 和 2015 中的 C++ 编译器错误 C2280“试图引用已删除的函数”

C++错误C2280 - 试图引用一个已删除的函数 - 在基元类型上。

试图找到已删除的函数

在 qt C++ 信号和槽中使用已删除函数错误

C++ 错误(C2280)试图访问已删除的函数 [关闭]