草庐IT

c++ - 在 Visual Studio 中调用 std::swap 时的 std::bad_function_call

coder 2024-02-19 原文

我正在尝试将我的代码从 Linux 移植到 Windows。但是,对于 Visual Studio,我的代码因以下错误而崩溃:

Microsoft C++ exception: std::bad_function_call at memory location

这是我的代码:

#include <functional>

class Foo {
public:
    Foo(int) : m_deleter{ []() {} } {}
    Foo(const Foo &) = delete;
    Foo(Foo &&) = default;
    Foo & operator=(const Foo &) = delete;
    Foo & operator=(Foo &&) = default;
    ~Foo()
    {
        m_deleter();
    }
private:
    std::function<void()> m_deleter;
};

int main() {
    Foo foo(1);
    Foo bar(2);
    std::swap(foo, bar);
}

当我使用 std::swap 时它崩溃了。在 Linux 中,它运行完美。

奇怪的是,当我尝试 compile it online通过 GCC 它也不起作用。我做错了什么,为什么在家里用 Clang (3.5) 工作。

编辑:事实证明它在 Visual Studio 2015 和 GCC 4.9.2 中崩溃,但在 Clang 3.5 中没有。

最佳答案

简介

该行为的原因很简单; m_deleterFoo 的析构函数中被无条件调用,即使在它不可调用的情况下也是如此。

std::swap 的直接实现创建了一个临时文件来保存两个操作数之一的中间结果,这个临时文件没有可调用的 m_deleter


什么是std::bad_function_call
std::bad_function_call如果您尝试调用 std::function 将被抛出它没有要调用的有效目标。



阐述

我们可以将您的测试用例缩减为以下更明确的片段:

 1 #include <functional>
 2 #include <utility>

 3 struct A {
 4   A () 
 5     : _cb {[]{}}
 6   { } 
 7   
 8   A (A&& src)
 9     : _cb (std::move (src._cb))
10   { } 
11   
12   A& operator= (A&& src)
13   {
14     _cb = std::move (src._cb);
15     return *this;
16   } 
17   
18 
19   ~A () {
20     _cb ();
21   } 
22   
23   std::function<void()> _cb;
24 };

25 void swap (A& lhs, A& rhs) {
26   A temporary = std::move (lhs);
27           lhs = std::move (rhs);
28           rhs = std::move (temporary);
29 } 

30 int main() {
31   A x, y;
32   swap (x, y);
33 } 

问题

当离开 swaptemporary 将被销毁,这反过来将尝试调用 _cb - 问题是 temporary。 _cb 已从 14移出;它不再可调用并抛出异常。


解决方案

~A::A () {
  if (_cb) // check if callable
    _cb (); 
}

关于c++ - 在 Visual Studio 中调用 std::swap 时的 std::bad_function_call,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28937394/

有关c++ - 在 Visual Studio 中调用 std::swap 时的 std::bad_function_call的更多相关文章

  1. ruby-on-rails - rails : "missing partial" when calling 'render' in RSpec test - 2

    我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou

  2. ruby - 在 Ruby 中实现 `call_user_func_array` - 2

    我怎样才能完成http://php.net/manual/en/function.call-user-func-array.php在ruby中?所以我可以这样做:classAppdeffoo(a,b)putsa+benddefbarargs=[1,2]App.send(:foo,args)#doesn'tworkApp.send(:foo,args[0],args[1])#doeswork,butdoesnotscaleendend 最佳答案 尝试分解数组App.send(:foo,*args)

  3. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  4. 使用 ACL 调用 upload_file 时出现 Ruby S3 "Access Denied"错误 - 2

    我正在尝试编写一个将文件上传到AWS并公开该文件的Ruby脚本。我做了以下事情:s3=Aws::S3::Resource.new(credentials:Aws::Credentials.new(KEY,SECRET),region:'us-west-2')obj=s3.bucket('stg-db').object('key')obj.upload_file(filename)这似乎工作正常,除了该文件不是公开可用的,而且我无法获得它的公共(public)URL。但是当我登录到S3时,我可以正常查看我的文件。为了使其公开可用,我将最后一行更改为obj.upload_file(file

  5. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  6. ruby - 怎么来的(a_method || :other) returns :other only when assigning to a var called a_method? - 2

    给定以下方法:defsome_method:valueend以下语句按我的预期工作:some_method||:other#=>:valuex=some_method||:other#=>:value但是下面语句的行为让我感到困惑:some_method=some_method||:other#=>:other它按预期创建了一个名为some_method的局部变量,随后对some_method的调用返回该局部变量的值。但为什么它分配:other而不是:value呢?我知道这可能不是一件明智的事情,并且可以看出它可能有多么模棱两可,但我认为应该在考虑作业之前评估作业的右侧...我已经在R

  7. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  8. ruby - 调用其他方法的 TDD 方法的正确方法 - 2

    我需要一些关于TDD概念的帮助。假设我有以下代码defexecute(command)casecommandwhen"c"create_new_characterwhen"i"display_inventoryendenddefcreate_new_character#dostufftocreatenewcharacterenddefdisplay_inventory#dostufftodisplayinventoryend现在我不确定要为什么编写单元测试。如果我为execute方法编写单元测试,那不是几乎涵盖了我对create_new_character和display_invent

  9. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

  10. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

随机推荐