在 C++11 中,可以显式默认一个特殊成员函数,如果它的隐式生成被自动阻止。
但是,显式默认一个特殊成员函数只是撤销手动声明一些其他特殊成员函数(复制操作、析构函数等)导致的隐式删除,它不会强制编译器生成函数和代码即使函数实际上无法生成,也被认为是良构的。
考虑以下场景:
struct A
{
A () = default;
A (const A&) = default;
A (A&&) = delete; // Move constructor is deleted here
};
struct B
{
B () = default;
B (const B&) = default;
B (B&&) = default; // Move constructor is defaulted here
A a;
};
B中的移动构造函数不会被编译器生成,因为这样做会导致编译错误(A的移动构造函数被删除)。如果不显式删除 A 的构造函数,将按预期生成 B 的移动构造函数(复制 A,而不是移动它)。
尝试移动这样的对象将默默地使用复制构造函数:
B b;
B b2 (std::move(b)); // Will call B's copy constructor
有没有办法强制编译器生成函数,或者在不能生成函数时发出编译错误?没有这种保证,如果单个删除的构造函数可以禁用整个对象层次结构的移动,就很难依赖默认的移动构造函数。
最佳答案
有一种方法可以检测像 A 这样的类型。但前提是类型显式删除了移动构造函数。如果移动构造函数隐式生成为已删除,则它将不参与重载决议。这就是为什么 B 是可移动的,尽管 A 不是。 B 默认是移动构造函数,这意味着它会被隐式删除,因此会发生复制。
B 因此是可移动构造的。但是,A 不是。所以这很简单:
struct B
{
static_assert(is_move_constructible<A>::value, "Oops...");
B () = default;
B (const B&) = default;
B (B&&) = default; // Move constructor is defaulted here
A a;
};
现在,没有通用方法可以使任何包含仅复制类型的类型执行您想要的操作。也就是说,您必须分别对每种类型进行静态断言;您不能在默认移动构造函数中放置一些语法来使移动 B 的尝试失败。
部分原因与向后兼容性有关。想一想声明用户定义的复制构造函数的所有 C++11 之前的代码。根据 C++11 中移动构造函数生成的规则,它们都将删除移动构造函数。这意味着 T t = FuncReturningTByValue(); 形式的任何代码都会失败,即使它在 C++98/03 中通过调用复制构造函数工作得很好。因此,如果无法生成移动构造函数,则通过复制而不是移动来解决此问题。
但由于 = default 表示“做你通常会做的事”,它还包括忽略隐式删除的移动构造函数的特殊重载解析行为。
关于c++ - 强制执行显式默认的特殊成员函数生成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35204767/
我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
这是在Ruby中设置默认值的常用方法:classQuietByDefaultdefinitialize(opts={})@verbose=opts[:verbose]endend这是一个容易落入的陷阱:classVerboseNoMatterWhatdefinitialize(opts={})@verbose=opts[:verbose]||trueendend正确的做法是:classVerboseByDefaultdefinitialize(opts={})@verbose=opts.include?(:verbose)?opts[:verbose]:trueendend编写Verb
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
我遵循了教程http://gettingstartedwithchef.com/,第1章。我的运行list是"run_list":["recipe[apt]","recipe[phpap]"]我的phpapRecipe默认Recipeinclude_recipe"apache2"include_recipe"build-essential"include_recipe"openssl"include_recipe"mysql::client"include_recipe"mysql::server"include_recipe"php"include_recipe"php::modul
我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问
两者都可以defsetup(options={})options.reverse_merge:size=>25,:velocity=>10end和defsetup(options={}){:size=>25,:velocity=>10}.merge(options)end在方法的参数中分配默认值。问题是:哪个更好?您更愿意使用哪一个?在性能、代码可读性或其他方面有什么不同吗?编辑:我无意中添加了bang(!)...并不是要询问nobang方法与bang方法之间的区别 最佳答案 我倾向于使用reverse_merge方法:option
我正在尝试用ruby中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了
对于Rails模型,是否可以/建议让一个类的成员不持久保存到数据库中?我想将用户最后选择的类型存储在session变量中。由于我无法从我的模型中设置session变量,我想将值存储在一个“虚拟”类成员中,该成员只是将值传递回Controller。你能有这样的类(class)成员吗? 最佳答案 将非持久属性添加到Rails模型就像任何其他Ruby类一样:classUser扩展解释:在Ruby中,所有实例变量都是私有(private)的,不需要在赋值前定义。attr_accessor创建一个setter和getter方法:classUs
我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin