使用大括号初始化进行赋值的类型推导规则是什么?

What is the rule for type deduction for assignment using brace initialization?

在下面的代码中,令我惊讶的是,{ } 似乎创建了 int 的默认初始化实例,而不是 A

struct A {
  int i = 1;
  A() = default;
  A& operator=(const A& a) {
    this->i = a.i;
    return *this;
  }
  A& operator=(int i) {
    this->i = i;
    return *this;
  }
};

int main() {
  A a;
  a = { };
  return a.i;
}

用什么规则解析a = { }?我认为 a = { } 必须等同于 a = decltype(a){ }.

此处发生的初始化类型的正确术语是什么?

这是一个 example 神栓。在 -O0 处,程序集准确显示了正在使用的函数。除非删除 int 赋值运算符,否则会调用 A::operator=(int)

首先,braced-init-list {} 可用于初始化 intA,它们也被视为转换,而 [=10] 的转换=] 到 int 在重载决策中获胜,因为从 {}A 的转换(通过 A::A())被认为是用户定义的转换。

赋值运算符并不特殊,编译器只是收集重载集中所有可行的operator=,然后通过重载决策来决定应该选择哪一个。如果你添加另一个 operator=(float) 你会得到一个不明确的错误,因为从 {}int 和从 {}float 的转换都被认为是标准转换相同排名,胜过用户定义的转换。