C++ 这是否应该含糊不清?(隐式转换)

C++ 这是否应该含糊不清?(隐式转换),c++,standards,casting,C++,Standards,Casting,EDG/Comeau和MSVC允许代码,而GCC 4.4.4、CLANG和BCC允许代码 以模棱两可为由予以拒绝 >一位C++委员会成员对此进行了回答(最初): 这并不含糊;A(常数A&) 构造函数优于A(const char*)构造函数。康斯塔酒店& 参数直接绑定到结果 转换函数的 转换顺序被认为是 是否遵循用户定义的转换 通过身份转换 (13.3.3.1.4p1)。常量字符* 参数是用户定义的转换 然后是资格证书 转换,所以情况更糟 然后,他接着说了这个 事实上,我错了。尽管如此 真的,第

EDG/Comeau和MSVC允许代码,而GCC 4.4.4、CLANG和BCC允许代码 以模棱两可为由予以拒绝

<> >一位C++委员会成员对此进行了回答(最初):

这并不含糊;A(常数A&) 构造函数优于A(const char*)构造函数。康斯塔酒店& 参数直接绑定到结果 转换函数的 转换顺序被认为是 是否遵循用户定义的转换 通过身份转换 (13.3.3.1.4p1)。常量字符* 参数是用户定义的转换 然后是资格证书 转换,所以情况更糟

然后,他接着说了这个

事实上,我错了。尽管如此 真的,第二次转换 用户定义转换中的序列 sequence是一个打破僵局的程序,看起来更像 接近13.3.3.2p3时 在最后一颗子弹旁边,显示 仅当两个 序列包含相同的 用户定义的转换顺序,以及 本例中的情况并非如此。 因为一个构造函数的转换 序列使用B::运算符A()和 其他用途b::运算符char*(), 两者之间没有平局 用户定义的转换序列和 它们是模棱两可的

我的问题是

13.3.3.2 p3规定

两个隐式转换序列 同样的形式难以区分 转换序列,除非 以下规则适用

根据我的理解,关键词是“以下规则之一”。 这并不意味着项目符号表示“相同的转换顺序” 覆盖上面所有的。我会认为“S1的排名更好 而S2“的等级将适用吗?

免责声明:这些部分的标准非常复杂,因此我的理解可能完全错误

最佳可行功能的标准定义(13.3.3):

根据这些定义,一个可行的 函数F1被定义为更好的函数 功能比另一个可行的功能更重要 如果对于所有参数i,ICSi(F1)为 转换顺序不比 ICSi(F2),然后

[……]

  • 上下文是通过用户定义转换进行的初始化(参见8.5, 13.3.1.5和13.3.1.6)以及 返回到目的地的F1类型 类型(即实体的类型 初始化)是一个更好的方法 转换顺序超过标准 从返回的转换序列 将F2的类型转换为目标类型
如果我理解正确,正在构造的对象的类型在这里有其重要性,这将使
A::A(const A&)
成为更好的候选者。



请参阅Johannes的评论,了解此答案不正确的原因:这确实是不明确的,因为Chubsdad指出了原因。

是的,就我对第13.3.3.2条的解释而言,预期结果是不明确的

将类型为“B”的参数“v”与“A”的任一重载构造函数的参数匹配需要用户定义的转换。这两个序列都具有转换秩

我的解释是,以下13.3.3.2美元的报价适用

[…]用户定义的转换序列 U1是一个更好的转换序列 而不是另一个用户定义的转换 序列U2如果它们包含相同的 用户定义的转换函数或 构造函数,如果是第二个标准 U1的转换顺序较好 比第二个标准转换 U2的顺序。


这两个函数都调用类“B”中的不同转换函数。因此,我认为第一个条件本身并不满足,因此预期结果是模糊的,因为转换序列的NITER优于另一个。

证明C++过于复杂,因为C++与Cube成员联系,您不应该要求他提交一个问题吗?(或者检查是否提交到)我没有说有问题,我实际上是在试图理解标准。有趣的是,知道EDG和MSVC允许哪种转换。但是这也是我不喜欢隐式转换的原因之一,如果我需要转换,我会要求它的,谢谢。explicit=good,implicit=bad绝对相关,+1,但在提到的两个上下文中,13.3.1.5只涉及非类类型的初始化(比如
int
),13.3.1.6只涉及引用的初始化。所以我认为它们不适用于这里。@j_random_hacker:是的,但8.5涵盖了初始化或几乎所有内容else@icecrime:你是对的,但是情节变厚了:根据8.5/12,
as(v)是直接初始化--对吗?然后,8.5/14中的第6个项目符号适用。它太大了,不能在这里引用,但关键点是它没有提到“用户定义转换”这个词——这与下一个涵盖(一些)副本初始化情况的项目符号不同。所以我不认为你引用的片段适用于这里,我的结论是
as(v)不明确,但
A s=v应该选择
A(const A&)
ctor。我进一步得出结论,C++的初始化规则不可能更令人困惑。是的,这取决于对第一个代码段是否适用的解释。。。它明确提到13.3.1.5和13.3.1.6,但没有提到13.3.1.3(这是本案中的相关条款),这一事实使我认为它没有提到;但很明显,用户定义的转换正在进行,所以可能会发生。根本问题是“通过用户定义的转换进行初始化”实际上并不是一个在AICT任何地方定义的术语。是的,这显然是不明确的,因为您提到的确切原因。我不知道为什么这不是公认的答案。它直接指出了它是如何产生的,为什么产生的,以及它是模棱两可的。然而,它有“转换”等级是错误的。正如您稍后所说,您有两个用户定义的转换
 struct A 
 {
     A(const A& src);
     A(const char* src);
 };
 struct B 
 {
     operator A();
     operator char*();
 };
 void test()  
 {
     B v;
     A s(v);
 }