gpt4 book ai didi

c++ - 这些转换中的哪些应该是不明确的?

转载 作者:IT老高 更新时间:2023-10-28 23:02:39 27 4
gpt4 key购买 nike

我有一些像下面这样的代码:

class bar;

class foo
{
public:
operator bar() const;
};

class bar
{
public:
bar(const foo& foo);
};

void baz() {
foo f;
bar b = f; // [1]

const foo f2;
bar b2 = f2; // [2]
}

GCC 在 [2] 但不是 [1] 处给出错误。 Clang 两者都出错,显然 MSVC 两者都出错。谁是对的?

最佳答案

tl;博士

暧昧。 (另外,如果你停在 tl;dr,那么 language-lawyer 标签可能不是你的一杯茶。^_^)

剧透

两位候选人都有一个 const foo&参数,同样绑定(bind)到 const foofoo论据。没有其他规则更喜欢一种或另一种功能。

将其分解为 current C++ working draft

初始化程序 [dcl.init]

在这两种情况下

  • 我们正在执行复制初始化 ( [dcl.init]/15 )
  • 目标类型是类类型( [dcl.init]/17.6 )
  • (X) 初始化表达式不是纯右值 ( [dcl.init]/17.6.1 )
  • (X) 源类型与目标类型不同或派生自目标类型 ( [dcl.init]/17.6.2 )
  • [over.match.copy]枚举用户定义的转换序列和最佳选择 overload resolution .

  • 通过用户定义的转换复制初始化类 [over.match.copy]
    T是被初始化的类型,在这两种情况下都是 bar . S是初始化表达式的类型,在两种情况下 fooconst foo分别。
  • 转换 T 的构造函数是候选人 ( [over.match.copy]/1.1 )
  • bar::bar(const foo& foo);是候选人
  • 初始化表达式的类型是 _cv_ S如此不明确 conversion functions被认为是:( [over.match.copy]/1.2 )
  • foo::operator bar() const不隐藏在 foo 内或在 const foo 内, 并产生 barT 相同,因此是一个候选。

  • 所以我们的候选列表在两种情况下都是相同的:
  • bar::bar(const foo& foo)
  • foo::operator bar() const

  • 在这两种情况下,我们都有一个 user-defined conversion包括:
  • 源类型到用户定义的转换参数的标准转换
  • 用户定义的转换(上述两个函数之一)到结果类型
  • 结果类型到目标类型的标准转换

  • 如果我们选择构造函数,则“结果类型”是“其结果对象由构造函数初始化的目标类型的 cv 非限定版本的纯右值”( [dcl.init]/17.6.3 ),因此对于两个候选函数,第二个标准转换是 身份 ( bar -> bar )。

    过载解析 [over.match]

    子集可行的候选函数 [over.match.viable]

    [dcl.init]/17.6.3 ,初始化表达式将成为所选调用的参数,在两种情况下 fooconst foo分别。
    bar::bar(const foo& foo)
  • 参数列表中的一个参数,正好是一个参数。 ( [over.match.viable]/2.1 )
  • 没有关联的约束 ( [over.match.viable]/3 )
  • 隐式转换序列存在于 fooconst fooconst foo& ( [over.match.viable]/4 )
  • 初始标准转换为 身份转换 在这两种情况下:[over.best.ics]/5 => [over.ics.ref]/1对于直接引用绑定(bind):
  • const foofoo 均引用兼容和 const fooconst比两者都更符合 cv 资格 const什么都没有。 [dcl.init.ref]/4
  • const foo&直接绑定(bind)到左值 foo和一个左值 const foo . [dcl.init.ref]/5
  • 可行
  • foo::operator bar() const
  • 参数列表中的一个参数,正好是一个 implicit object参数。 ( [over.match.viable]/2.1 )
  • 隐式对象参数是 const foo&在这两种情况下 ( [over.match.funcs]/4 )
  • 没有关联的约束 ( [over.match.viable]/3 )
  • 隐式转换序列存在于 fooconst fooconst foo& ( [over.match.viable]/4 )
  • 初始标准转换为 身份转换在这两种情况下,请参见上文。
  • 可行

  • 选择最佳可行函数 [over.best.ics]

    两者都是 身份 => 用户定义的转换 => 身份 ,即是 user-defined conversion sequences .

    排名转换序列 over.ics.rank

    我们可以在序列之间建立排名吗?仅当 one of the following applies
  • (X) 非列表初始化序列 ( [over.ics.rank]/3 )
  • (X) 不是标准的转换序列 ( [over.ics.rank]/3.2 )
  • (X) 这两个序列不包含“相同的用户定义的转换函数或构造函数或 [...] 在聚合初始化中初始化相同的类”( [over.ics.rank]/3.3 )

  • 转换序列为 难以区分 ,即既不是更好也不是更糟

    最佳可行函数 over.match.best

    任一功能是“更好”的功能吗?仅当 one of the following applies
  • (X) 也不是更好的转换序列 ( [over.match.best]/1.3 )
  • (X) 第二个标准转换相同 ( [over.match.best]/1.4 )
  • (X) 不直接引用将引用绑定(bind)到函数类型 ( [over.match.best]/1.5 )
  • (X) 也不是函数模板特化( [over.match.best]/1.6[over.match.best]/1.7 )
  • (X) 都不受约束 ( [over.match.best]/1.8 )
  • (X) 一个是 bar 的构造函数,但另一个不是 bar 基类的构造函数( [over.match.best]/1.9 )
  • (X) 没有推导的类类型 ([[over.match.best]/1.10]( http://eel.is/c++draft/over.match.best#1.10[over.match.best]/1.11
  • (X) 也不是构造函数模板 ( [over.match.best]/1.12 )

  • 两者都不是“更好”的功能,因此 调用格式错误 . [over.match.best]/2

    关于c++ - 这些转换中的哪些应该是不明确的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45636437/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com