没有移动构造函数但具有接受 const T& 参数的复制构造函数的类型,满足 std::is_move_constructible。例如,在以下代码中:
#include <type_traits>
struct T {
T(const T&) {}
//T(T&&) = delete;
};
int main() {
static_assert(std::is_move_constructible<T>::value, "not move constructible");
return 0;
}
T 将没有隐式移动构造函数,因为它有一个用户定义的复制构造函数。
但是,如果我们取消注释移动构造函数的显式删除,代码将不再编译。为什么是这样?我本来希望显式复制构造函数仍然满足 std::is_move_constructible。
重载是否起作用,选择声明的移动构造函数然后因为它被删除而失败?
如果标准规定了 no implicit move ctor 和 deleted move ctor 类之间的移动构造性之间的差异,请引用,如果可能,请给出基本原理(例如“提供一种禁止移动施工的设施”——首先想到的就是)。
最佳答案
这是对我的第一个答案的全面修改,以纠正所说的一些错误并引用标准并指出提问者希望的一些细节。
什么std::is_move_constructible实际做
如果 T是一个结构然后std::is_move_constructible<T>计算结果为 std::is_constructible<T,T&&> . std::is_constructible<T,U>如果 T x(y) 则有效是一些 y 的格式良好的表达式类型 U .因此对于 std::is_move_constructible<T>说真的,T x(std::move(y)) y 的格式必须正确类型 T .
引用标准:
The predicate condition for a template specialization is_constructible<T, Args...>
shall be satisfied if and only if the following variable definition would
be well-formed for some invented variable t:
T t(create<Args>()...);
(...)
Template: template <class T> struct is_move_constructible;
Condition: For a referenceable type T, the same result as is_constructible<T, T&&>::value,
otherwise false.
Precondition: T shall be a complete type, (possibly cv-qualified) void,
or an array of unknown bound.
创建移动构造函数时
标准规定,仅当用户未声明复制构造函数、移动构造函数、赋值运算符或析构函数时,才会创建默认移动构造函数。
If the definition of a class X does not explicitly declare a move
constructor, one will be implicitly declared as defaulted if and only if
—X does not have a user-declared copy constructor,
—X does not have a user-declared copy assignment operator,
—X does not have a user-declared move assignment operator, and
—X does not have a user-declared destructor
但是,该标准允许您使用类右值初始化类左值引用。
Otherwise, the reference shall be an lvalue reference to a non-volatile const type
(i.e., cv1 shall be const), or the reference shall be an rvalue reference.
—If the initializer expression is an xvalue (but not a bit-field),
class prvalue, array prvalue or function lvalue and “cv1 T1”
is reference-compatible with “cv2 T2”, or (...)
then the reference is bound to the value of the initializer expression (...)
(or, in either case, to an appropriate base class subobject).
因此,如果你有一个复制构造函数 T::T(S& other)和一个对象 y类型 T&& ,即对 T 的右值引用,然后 y与 T& 引用兼容和 T x(y)是调用复制构造函数的有效表达式 T::T(S&) .
示例结构的作用
让我以您的第一个示例为例,删除 const关键字,以避免十次声明引用需要比初始值设定项更具 cv 限定。
struct S {
S(S&) {}
};
让我们检查一下情况。由于存在用户定义的复制构造函数,因此没有隐式默认的移动构造函数。然而,
如果 y是 S 类型,然后 std::move(y) , 类型为 S&& , 与类型 S& 的引用兼容.因此S x(std::move(y))完全有效并调用复制构造函数S::S(const S&) .
第二个例子做了什么
struct T {
T(T&) {}
T(T&&) = delete;
};
同样,没有定义移动构造函数,因为有一个用户定义的复制构造函数和一个用户定义的移动构造函数。再次让 y类型为 T并考虑T x(std::move(y)) .
但是,这一次表达式中可以容纳多个构造函数,因此执行了重载选择。仅尝试使用最专业的匹配构造函数,因此只有移动构造函数 T::T(T&&)试图调用。但是move构造函数被删除了,所以这是无效的。
结论
第一个结构,S , 可以使用它的复制构造函数来执行类似移动的表达式,因为它是这个表达式最专业的构造函数。
第二个结构,T ,必须使用其显式声明的移动构造函数来执行类似移动的表达式,因为它是最专业的。然而,该构造函数被删除,移动构造表达式失败。
关于c++ - 了解 `std::is_move_constructible`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33939644/
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
如何将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.你能做的最好的事情是:
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
我正在尝试使用“updated_at”字段的日期时间范围查询数据库。前端在JSON数组中发送查询:["2015-09-0100:00:00","2015-10-0223:00:00"]在RailsController中,我使用以下方法将两个字符串解析为DateTime:start_date=DateTime.parse(params[:date_range_arr][0])end_date=DateTime.parse(params[:date_range_arr][1])#...@events=@events.where('updated_atBETWEEN?AND?,start_d
我遇到了这个奇怪的错误.../Users/gideon/Documents/ca_ruby/rubytactoe/lib/player.rb:13:in`gets':Isadirectory-spec(Errno::EISDIR)player_spec.rb:require_relative'../spec_helper'#theuniverseisvastandinfinite...itcontainsagame....butnoplayersdescribe"tictactoegame"docontext"theplayerclass"doit"musthaveahumanplay
我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“
我经常将预配置的lambda插入可枚举的方法中,例如“map”、“select”等。但是“注入(inject)”的行为似乎有所不同。例如与mult4=lambda{|item|item*4}然后(5..10).map&mult4给我[20,24,28,32,36,40]但是,如果我制作一个2参数lambda用于像这样的注入(inject),multL=lambda{|product,n|product*n}我想说(5..10).inject(2)&multL因为“inject”有一个可选的单个初始值参数,但这给了我......irb(main):027:0>(5..10).inject
是否有self验证的问题列表。看着那个,我可以确定我知道。我应该复习一下。在学习的过程中,我列了一个这样的list,但它只包含我在某处听说过的项目。我需要一段时间才能找到新的东西。 最佳答案 以下是针对ruby和Rails的一些测试列表。证书名称:RubyonRails谁提供:oDeskIncorporation认证费用:免费网站:https://www.odesk.com/tests/985?pos=0证书名称:RubyonRails提供者:Techgig.com(TimesBusinessSolutionsLimited(T
有没有办法让Ruby能够做这样的事情?classPlane@moved=0@x=0defx+=(v)#thisiserror@x+=v@moved+=1enddefto_s"moved#{@moved}times,currentxis#{@x}"endendplane=Plane.newplane.x+=5plane.x+=10putsplane.to_s#moved2times,currentxis15 最佳答案 您不能在Ruby中覆盖复合赋值运算符。任务在内部处理。您应该覆盖+,而不是+=。plane.a+=b与plane.a=
我想覆盖store_accessor的getter。可以查到here.代码在这里:#Fileactiverecord/lib/active_record/store.rb,line74defstore_accessor(store_attribute,*keys)keys=keys.flatten_store_accessors_module.module_evaldokeys.eachdo|key|define_method("#{key}=")do|value|write_store_attribute(store_attribute,key,value)enddefine_met