- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
Clang 6、clang 7 和 gcc 7.1、7.2 和 7.3 都同意以下是有效的 C++17 代码,但在 C++14 和 C++11 下是模棱两可的。 MSVC 2015 和 2017 也接受它。但是,即使在 c++17 模式下,gcc-8.1 和 8.2 也会拒绝它:
struct Foo
{
explicit Foo(int ptr);
};
template<class T>
struct Bar
{
operator T() const;
template<typename T2>
explicit operator T2() const;
};
Foo foo(Bar<char> x)
{
return (Foo)x;
}
接受它的编译器选择模板化显式转换函数 Bar::operator T2()
.
拒绝它的编译器同意以下之间存在歧义:
Bar<char>
的隐式用户定义转换至char
,然后是char
的隐式内置转换至int
,然后是显式构造函数 Foo(int)。那么,哪个编译器是正确的? C++14和C++17在标准上有什么相关区别?
附录:实际错误信息
这里是 gcc-8.2 -std=c++17
的错误. gcc-7.2 -std=c++14
打印同样的错误:
<source>: In function 'Foo foo(Bar<char>)':
<source>:17:17: error: call of overloaded 'Foo(Bar<char>&)' is ambiguous
return (Foo)x;
^
<source>:3:14: note: candidate: 'Foo::Foo(int)'
explicit Foo(int ptr);
^~~
<source>:1:8: note: candidate: 'constexpr Foo::Foo(const Foo&)'
struct Foo
^~~
<source>:1:8: note: candidate: 'constexpr Foo::Foo(Foo&&)'
这是来自 clang-7 -std=c++14
的错误(clang-7 -std=c++17
接受代码):
<source>:17:12: error: ambiguous conversion for C-style cast from 'Bar<char>' to 'Foo'
return (Foo)x;
^~~~~~
<source>:1:8: note: candidate constructor (the implicit move constructor)
struct Foo
^
<source>:1:8: note: candidate constructor (the implicit copy constructor)
<source>:3:14: note: candidate constructor
explicit Foo(int ptr);
^
1 error generated.
最佳答案
这里有几种力量在起作用。要了解发生了什么,让我们检查一下 (Foo)x
的位置。应该带领我们。首先,c 风格的类型转换相当于 static_cast
在这种特殊情况下。静态转换的语义是直接初始化结果对象。由于结果对象是类类型,[dcl.init]/17.6.2告诉我们它的初始化如下:
Otherwise, if the initialization is direct-initialization, or if it is copy-initialization where the cv-unqualified version of the source type is the same class as, or a derived class of, the class of the destination, constructors are considered. The applicable constructors are enumerated ([over.match.ctor]), and the best one is chosen through overload resolution. The constructor so selected is called to initialize the object, with the initializer expression or expression-list as its argument(s). If no constructor applies, or the overload resolution is ambiguous, the initialization is ill-formed.
所以重载决议来选择Foo
的构造函数打电话。如果重载决议失败,则程序格式错误。在这种情况下,它不应该失败,即使我们有 3 个候选构造函数。那些是Foo(int)
, Foo(Foo const&)
和 Foo(Foo&&)
.
首先,我们需要复制初始化int
作为构造函数的参数,这意味着从 Bar<char>
中找到一个隐式转换序列至int
.由于您从 Bar<char>
提供的用户定义的转换运算符至char
不是显式的,我们可以使用它来从隐式对话序列 Bar<char> -> char -> int
.
对于其他两个构造函数,我们需要绑定(bind)一个对 Foo
的引用。 .但是,我们不能这样做。根据[over.match.ref]/1 :
Under the conditions specified in [dcl.init.ref], a reference can be bound directly to a glvalue or class prvalue that is the result of applying a conversion function to an initializer expression. Overload resolution is used to select the conversion function to be invoked. Assuming that “cv1 T” is the underlying type of the reference being initialized, and “cv S” is the type of the initializer expression, with S a class type, the candidate functions are selected as follows:
- The conversion functions of S and its base classes are considered. Those non-explicit conversion functions that are not hidden within S and yield type “lvalue reference to cv2 T2” (when initializing an lvalue reference or an rvalue reference to function) or “ cv2 T2” or “rvalue reference to cv2 T2” (when initializing an rvalue reference or an lvalue reference to function), where “cv1 T” is reference-compatible ([dcl.init.ref]) with “cv2 T2”, are candidate functions. For direct-initialization, those explicit conversion functions that are not hidden within S and yield type “lvalue reference to cv2 T2” or “cv2 T2” or “rvalue reference to cv2 T2,” respectively, where T2 is the same type as T or can be converted to type T with a qualification conversion ([conv.qual]), are also candidate functions.
唯一可以为我们生成 Foo
类型的泛左值或纯右值的转换函数是您指定的显式转换函数模板的特化。但是,由于函数参数的初始化不是直接初始化,我们不能考虑显式转换函数。所以我们不能在重载决议中调用复制或移动构造函数。剩下的只有构造函数采用 int
.所以重载决议是成功的,应该就是这样。
那么为什么有些编译器会觉得它不明确,或者调用模板化转换运算符呢?好吧,由于标准中引入了保证复制省略,因此注意到 (CWG issue 2327) 用户定义的转换函数也应该有助于复制省略。今天,根据标准的干信,他们没有。但我们真的很希望他们这样做。虽然具体应该如何完成的措辞仍在制定中,但似乎一些编译器已经开始尝试实现它。
你看到的就是那个实现。在这里,扩展复制省略的反作用力会干扰重载解析。
关于C++17:显式转换函数 vs 显式构造函数 + 隐式转换——规则改变了吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53101121/
我需要在 nginx-ingress 版本上允许来自多个来源的请求:http://localhost:4200、http://localhost:4242 等1.7.1.但我无法对多个来源执行此操作,
我正在部署我使用 APIGILITY 开发的 API到 IIS。由于 IIS 不支持 .htaccess,我试图从 .htaccess 文件的内容创建 web.config 文件。我使用 IISv7.
我正在尝试更改上面 css 样式中的“宽度”规则。在“inspect element”中你可以看到宽度是1008px。我不希望它是 1008px 但它不会让我在 css 样式中更改它你可以看到它被“删
外部css赋值有2种方法,我用的是第一种;大多数网站使用第二种方法。我想知道我是否做错了! 第一种方法: 为几乎每个 css 规则创建一个类并在任何地方使用它们。 blah blah .f_
RDF使用 WEB 标识符 (URIs) 来标识资源,使用属性和属性值来描述资源 RDF 资源、属性和属性值 RDF使用 WEB 标识符来标识事物,并通过属性和属性值来描述资源。 关于资源、属性
我想挖掘特定的 rhs 规则。文档中有一个示例证明这是可能的,但仅适用于特定情况(如下所示)。先来一个数据集来说明我的问题: input {b=100002} 0.2500000 0.250000
我想让 nginx 从网站根目录(:http://localhost:8080/)提供一个静态文件,但它为我的代理通行证提供服务;它提供“/”规则而不是“=/”。 这是我的 nginx 配置的样子:
根据gnu make documentation , 如果一个规则通过一次调用生成多个目标(例如,一个配方执行一个带有多个输出文件的工具),你可以使用 '&:' 规则语法来告诉 make。但是,当在多
我已阅读Firebase Documentation并且不明白什么是 .contains()。 以下是文档中 Firebase 数据库的示例规则: { "rules": { "rooms"
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 6 年前。 Improv
我正在尝试做一些多态性练习,但我无法弄清楚这种多态性是如何工作的。我没有找到任何关于这种练习的深入信息。希望大家能给我一些解释。 练习1: class Top { public void m(
为了调试复杂的 XSLT 转换,我将其分为几个部分:首先构建 %.1.xml,然后使用它构建 %.2.xml ,最后构建 %.3.xml。一切正常,但如果我要求 Make 构建最后一个,Make 总是
我尝试了 hacerrank 的 slove 练习 Click我不知道如何添加这些规则: ► 它可以包含 4 个一组的数字,并用一个连字符“-”分隔。 ► 不得有 4 个或更多连续重复数字。 这是我的
我正在尝试编写一个小测验,我希望“再试一次”按钮遵循与“else”之前的“if”语句相同的规则 using System; public class Program { public stat
在我的 Spring/Boot Java 项目中,我有一组服务方法,例如以下一个: @Override public Decision create(String name, String descr
我正在阅读 Covariant virtual function .上面写着 假设 B::f 覆盖了虚函数 A::f。如果满足以下所有条件,A::f 和 B::f 的返回类型可能不同: 1) The
我工作的公司想要分发(在公共(public)链接中)具有内部签名的应用程序。我很确定 Apple 否认这种事情,但我在官方文档/契约(Contract)中没有找到任何相关信息。 有谁知道它到底是如何工
我是 CSS 新手。我观察到一个奇怪的 CSS 行为,其中一个元素具有以下 CSS 属性 .container .header{ color: #FFFFFF; font-size: 2em;
这个问题在这里已经有了答案: Is there a CSS selector for elements containing certain text? (21 个答案) 关闭 7 年前。
我有以下 CSS: workoutcal.css: .errorlist{ color:red; } 以下基本模板: base.html: {% load static %} {
我是一名优秀的程序员,十分优秀!