- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
在继续阅读本文之前,请阅读 Is there a difference in C++ between copy initialization and direct initialization?首先,确保您了解它在说什么。
这里我先总结一下规则(阅读标准n3225 8.5/16、13.3.1.3、13.3.1.4和13.3.1.5),
1) 对于直接初始化,所有的构造函数都会被认为是重载集,重载决议会根据重载决议规则选择最好的。
2) 对于复制初始化且源类型与目标类型相同或派生自目标类型,规则与上述相同,只是只有转换构造函数(没有显式的构造函数)将被视为重载集。这实际上意味着显式复制/移动构造函数不会被考虑到重载集中。
3)对于上面(2)中未包含的复制初始化情况(源类型与目标类型不同,并且不是从目标类型派生的),我们首先考虑可以从源类型转换为目标的用户定义转换序列类型或(当使用转换函数时)到其派生类。如果转换成功,则结果用于直接初始化目标对象。
3.1) 在此用户定义的转换序列中,根据 8.5/16 和 13.3.1.4 中的规则,将同时考虑转换 ctors(非显式 ctors)和非显式转换函数。
3.2)结果纯右值将直接初始化目标对象,如(1)中所列规则,见8.5/16。
好吧,规则说完了,让我们看一些奇怪的代码,我真的不知道我的推理哪里错了,或者只是所有的编译器都错了。请帮助我,谢谢。
struct A
{
A (int) { }
A() { }
explicit A(const A&) { }
};
struct B
{
operator A() { return 2; }
//1) visual c++ and clang passes this
//gcc 4.4.3 denies this, says no viable constructor available
};
int main()
{
B b;
A a = b;
//2) oops, all compilers deny this
}
据我了解,对于(1),
operator A() { return 2; }
因为C++有一个函数return作为copy-initialization的规则,根据上面的规则,2会先隐式转换为A,这样应该可以,因为A有一个构造函数A(int)。然后转换后的临时纯右值将用于直接初始化返回的对象,这也应该没问题,因为直接初始化可以使用显式复制构造函数。所以 GCC 是错误的。
对于(2),
A a = b;
按我的理解,首先b通过operator A()隐式转换为A,然后转换后的值直接初始化a,当然可以调用显式拷贝构造函数?因此这应该通过编译并且所有编译器都是错误的?
请注意,对于 (2),visual c++ 和 clang 都有类似的错误,“错误,无法从 B 转换为 A”,但是如果我删除 A 的复制构造函数中的显式关键字,错误就消失了。
感谢阅读。
编辑 1
因为还是有人没看懂我的意思,我引用8.5/16的以下标准,
Otherwise (i.e., for the remaining copy-initialization cases), user-defined conversion sequences that can convert from the source type to the destination type or (when a conversion function is used) to a derived class thereof are enumerated as described in 13.3.1.4, and the best one is chosen through overload resolution (13.3). If the conversion cannot be done or is ambiguous, the initialization is ill-formed. The function selected is called with the initializer expression as its argument; if the function is a constructor, the call initializes a temporary of the cv-unqualified version of the destination type. The temporary is a prvalue. The result of the call (which is the temporary for the constructor case) is then used to direct-initialize, according to the rules above, the object that is the destination of the copy-initialization. In certain cases, an implementation is permitted to eliminate the copying inherent in this direct-initialization by constructing the intermediate result directly into the object being initialized; see 12.2, 12.8.
请注意,它确实提到了在用户定义的转换之后直接初始化。这意味着,在我的理解中,以下代码应遵守我评论的规则,clang、coomeau online、visual c++ 都证实了这一点,但 GCC 4.4.3 不符合 (1) 和 (2)。虽然这是一个奇怪的规则,但它遵循了标准的推理。
struct A
{
A (int) { }
A() { }
explicit A(const A&) { }
};
int main()
{
A a = 2; //1)OK, first convert, then direct-initialize
A a = (A)2; //2)oops, constructor explicit, not viable here!
}
最佳答案
您声明了您的复制构造函数显式
(顺便说一句,为什么?),这意味着它不能再用于类对象的隐式复制。为了使用此构造函数进行复制,您现在必须使用直接初始化语法。见 12.3.1/2
2 An explicit constructor constructs objects just like non-explicit constructors, but does so only where the direct-initialization syntax (8.5) or where casts (5.2.9, 5.4) are explicitly used.
这个问题可以用下面更短的例子来说明
struct A {
A() {}
explicit A(const A&) {}
};
int main() {
A a;
A b = a; // ERROR: copy-initialization
A c(a); // OK: direct-initialization
}
这就是阻止所有转换工作的原因,因为它们都依赖于复制初始化,而复制初始化又依赖于隐式复制。并且您禁用了隐式复制。
此外,请参阅 Defect Report #152其中涵盖了这个特定问题。虽然我不确定“提议的决议”的后果应该是什么......
关于c++复制初始化和直接初始化,奇怪的情况,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4801136/
如果我在 C 中调用一个函数并传入一个结构(对那些 C++ 读者来说不是通过指针或引用),它会复制该对象。如果我传入一个包含数组的结构,它会复制该数组(如教授在类里面所说)。但是,如果我传入一个包含对
在 vim 等中,您可以使用 CTRLA 和 CTRLX 增加或减少光标所在的数字。然而,这会增加总数,但我想简单地增加光标正下方的数字。这有点难以描述,所以这就是我的意思: Ctrl+A usage
我正在将 Spring 4.3.2 项目升级到 Spring 5.1.5。我的一个测试用例开始因错误而失败。 ClassNotFoundException: org.hibernate.propert
我想在 Java 中分配一个直接 IntBuffer,比如说 10 亿个元素(64 位系统)。我知道的唯一方法是创建一个直接 ByteBuffer 并将其视为直接 IntBuffer。但是,4*1,0
我正在寻找特定的打印机或某些打印机上存在的技术(接口(interface)、标准、协议(protocol)),这使得可以使用 AJAX 从 Web 浏览器实现直接打印。 这意味着打印机必须: 网络接口
我正在寻求实现删除确认表单的最佳实践建议。 除其他选项外,以下页面包含删除按钮... /website/features/f/123 ...当点击一个简单的表单时,会在以下 url 下加载: /web
我正在使用直接 Web 远程处理库在我的应用程序中执行一些 ajax 调用。我有一个问题,我认为归结为服务调用的延迟响应。以下是我认为有问题的部分代码。问题出在 getDefaultReviewerT
我想替换 Javascript confirm() 函数以允许自定义按钮而不是 Yes/Cancel。我尝试搜索,但所有解决方案都是事件驱动的,例如 jquery 对话框(代码不等待响应但它是事件驱动
我知道有几个类似的问题,但是,其中的示例并没有说明问题,或者我无法从中获利 - 我真可耻。 所以我的问题是在带有 GUI 的简单应用程序中加载图像。例如: 我在 "D:\javaeclipseprog
我想用不同的颜色为表格的行着色,所以我正在使用它 table#news tr:nth-child(even) { background-color: red; } table#news
下面的测试代码不起作用 from("direct:start").setExchangePattern(ExchangePattern.InOnly).threads(5).delay(2000).b
我在 python 中实现的第一个项目之一是对棒渗流进行蒙特卡罗模拟。代码不断增长。第一部分是棍子渗滤的可视化。在宽度*长度的区域中,使用随机起始坐标和方向绘制具有一定长度的直棒的定义密度(棒/面积)
跟踪直接文件下载的最佳方法是什么?我找到了一些解决方案,例如这个: http://www.gayadesign.com/diy/download-counter-in-php-using-htacce
我在一个线程中有一个直接的 ByteBuffer(堆外),并使用 JMM 给我的一种机制将它安全地发布到另一个线程。 happens-before 关系是否扩展到由 ByteBuffer 包装的 na
当我测试直接 java.nio.ByteBuffer 的读取性能时,我注意到绝对读取平均比相对读取快 2 倍。此外,如果我比较相对读取与绝对读取的源代码,除了相对读取维护和内部计数器外,代码几乎相同。
我知道这个问题已经被问了无数次,并且在很多情况下都得到了答案。我相信我已经阅读了其中的大部分内容。不幸的是,我在这上面能找到的一切 简单说明 ElementRef.nativeElement不好,不要
回到一些 C 语言工作。 我的许多函数看起来像这样: int err = do_something(arg1, arg2, arg3, &result); 根据意图,结果由函数填充,返回值是调用的状态
当我将 XML 提交到 https://secure-test.WorldPay.com/jsp/merchant/xml/paymentService.jsp 时: Personalised
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
我的 Angular 路由行为有问题。刷新或输入的 url 像/user 总是将我重定向到/home。我还在 index.html 文件中设置了 。通过单击导航菜单按钮一切正常。但是一旦我尝试刷新页面
我是一名优秀的程序员,十分优秀!