【问题标题】:Overload resolution of constructors for different classes不同类的构造函数重载解析
【发布时间】:2019-10-24 14:58:17
【问题描述】:

考虑一下这段代码。

struct A {
    int i;
};

struct B {
    char c;
};

struct C {
    double d;
};

void f(A a);
void f(B b);
void f(C c);

void g()
{
    f({5});
}

这里我在f({5}); 中遇到了歧义。但似乎struct A的构造函数与{5}完全匹配,而第二个需要整数提升,而最后一个需要浮点转换。

那么为什么会有歧义呢?

【问题讨论】:

    标签: c++ c++11 constructor initializer-list overload-resolution


    【解决方案1】:

    即使序列中的第一个转换排名更差,两个转换序列最终都是用户定义的转换,因为它们都转换为用户定义的类型。

    [over.ics.user]

    1 用户定义的转换序列由初始标准组成 转换序列后跟用户定义的转换 ([class.conv]) 后跟第二个标准转换序列。

    隐式转换序列中任意位置的用户定义转换为整个序列提供“用户定义转换”等级。所以这两个转换序列实际上是同一等级的,因此没有一个比另一个更好。

    因此,函数调用不明确。

    【讨论】:

    • 另外,我认为,这里直接初始化是玩,虽然不是很明显。即使我们在结构中添加一些额外的字段,在初始化列表中元素数量较少的调用也会导致歧义,因为初始化列表可以转换为任何这些类型。
    • @Swift-FridayPie - {5}copy-list-initializtion。直接初始化看起来像A{5},在这种情况下不会有任何歧义。
    【解决方案2】:

    这是因为整数可以转换为双精度,因为双精度是一种更大的数据类型。它被称为隐式转换。

    这个函数调用g()可以去f(C c)以及f(A a)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-19
      • 1970-01-01
      • 2011-06-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多