jjzjj

c++ - 检测类型何时不需要调用其析构函数

coder 2024-02-24 原文

我正在编写一个 C++11 STL 兼容的分配器,我想知道如何检测调用它们的析构函数(在 allocator<T>::destroy 方法中)是安全的类型。 )

我已经编写了分配器(一个简单的分配器),据我所知,它确实有效。我问的原因是我在我的代码中收到警告(即在我的分配器的 destroy 方法中。)我在最高警告级别使用 VS2013 (vc12),警告是:

warning C4100: 'c' : unreferenced formal parameter

在这个方法中:

template <typename T>
class MyAlloc
{
    ...

    template <typename C>
    void destroy (C * c) // <-- this is the 'c' that the warning is referring to
    {
        c->~C ();
    }

    ...
};

如您所见,警告和代码都非常简单明了。在我看来,发出警告是因为该分配器用于的某些类没有析构函数(例如,因为它们是 POD 等)。随后,编译器在上述函数中删除了对析构函数的调用正在为此类类实例化分配器,然后发现函数体为空且参数未使用,发出警告。

我在想我可以写出上面的两个版本destroy方法,使用 enable_if 重载,并在不需要销毁的类的重载中将正文留空并且参数未命名。这行得通吗?

另一方面,这个警告是一个非常小的不便。我可以禁用此特定警告,它不会对我的代码库产生太大影响。毕竟,这几乎不是一个有用的警告。

但是,如果我确实尝试更改我的代码并检测不需要销毁的类,但这样做不可靠且效果不佳,我就会为各种痛苦和苦难打开闸门。因为如果我碰巧不销毁一个确实需要销毁的类的实例,那么只有上帝知道什么会(并且会)出错!因此,如果没有 100% 可靠且稳健的方法来检测并处理此类类,我宁愿保留警告,甚至附带警告。

重申一下,我的问题分为三个部分:

  1. 我对警告原因的分析是否正确?
  2. 我如何确定何时不调用类型的析构函数是安全的。换句话说,类型的析构函数何时完全无效,我如何检测到这一点(使用类型特征等)?
  3. 此检测是否始终可靠且完全可靠?

还有一个奖励问题:

我试过这个重载只是为了看看它是否有效:

template <typename C>
std::enable_if<std::is_trivially_destructible<C>::value>
destroy (C *)
{
}

template <typename C>
std::enable_if<!std::is_trivially_destructible<C>::value>
destroy (C * c)
{
    c->~C ();
}

请注意,我并不是说使用 std::is_trivially_destructible<>是要走的路;我只是想试试看是否enable_if在这种情况下工作。但是现在我遇到了很多这样的错误:

error C2668: 'MyAlloc<Whatever>::destroy' : ambiguous call to overloaded function
could be 'std::enable_if<false,void> MyAlloc<Whatever>::destroy<SomeType>(C *)'
or       'std::enable_if<true,void> MyAlloc<Whatever>::destroy<SomeType>(C *)'

似乎我在 enable_if 上做错了什么.我哪里错了?不应该 enable_if<false,...>由于 SFINAE 而被从决议中删除? SFINAE 是否也在类范围内发生?我也将感谢在这方面的任何帮助。

最佳答案

Microsoft say it's a bug ("limitation") of their compiler .

发明复杂的基于模板的解决方法是一项有趣的智力挑战,但在实际产品的代码审查中,我会比你说“过度设计”更快地抛弃任何此类东西。

template <typename C>
void destroy (C * c) // <-- this is the 'c' that the warning is referring to
{
    (void)c; // shut up you stupid compiler
    c->~C ();
}

关于c++ - 检测类型何时不需要调用其析构函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20946278/

有关c++ - 检测类型何时不需要调用其析构函数的更多相关文章

  1. ruby - 我需要将 Bundler 本身添加到 Gemfile 中吗? - 2

    当我使用Bundler时,是否需要在我的Gemfile中将其列为依赖项?毕竟,我的代码中有些地方需要它。例如,当我进行Bundler设置时:require"bundler/setup" 最佳答案 没有。您可以尝试,但首先您必须用鞋带将自己抬离地面。 关于ruby-我需要将Bundler本身添加到Gemfile中吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/4758609/

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

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

  3. ruby - rspec 需要 .rspec 文件中的 spec_helper - 2

    我注意到像bundler这样的项目在每个specfile中执行requirespec_helper我还注意到rspec使用选项--require,它允许您在引导rspec时要求一个文件。您还可以将其添加到.rspec文件中,因此只要您运行不带参数的rspec就会添加它。使用上述方法有什么缺点可以解释为什么像bundler这样的项目选择在每个规范文件中都需要spec_helper吗? 最佳答案 我不在Bundler上工作,所以我不能直接谈论他们的做法。并非所有项目都checkin.rspec文件。原因是这个文件,通常按照当前的惯例,只

  4. ruby - 在没有 sass 引擎的情况下使用 sass 颜色函数 - 2

    我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re

  5. ruby - Infinity 和 NaN 的类型是什么? - 2

    我可以得到Infinity和NaNn=9.0/0#=>Infinityn.class#=>Floatm=0/0.0#=>NaNm.class#=>Float但是当我想直接访问Infinity或NaN时:Infinity#=>uninitializedconstantInfinity(NameError)NaN#=>uninitializedconstantNaN(NameError)什么是Infinity和NaN?它们是对象、关键字还是其他东西? 最佳答案 您看到打印为Infinity和NaN的只是Float类的两个特殊实例的字符串

  6. ruby - 检查方法参数的类型 - 2

    我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)

  7. ruby - 如何在 Lion 上安装 Xcode 4.6,需要用 RVM 升级 ruby - 2

    我实际上是在尝试使用RVM在我的OSX10.7.5上更新ruby,并在输入以下命令后:rvminstallruby我得到了以下回复:Searchingforbinaryrubies,thismighttakesometime.Checkingrequirementsforosx.Installingrequirementsforosx.Updatingsystem.......Errorrunning'requirements_osx_brew_update_systemruby-2.0.0-p247',pleaseread/Users/username/.rvm/log/138121

  8. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  9. ruby-on-rails - 在 ruby​​ 中使用 gsub 函数替换单词 - 2

    我正在尝试用ruby​​中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了

  10. ruby - 在 Ruby 中有条件地定义函数 - 2

    我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin

随机推荐