C++ 不明确的重载、隐式转换和显式构造函数

C++ 不明确的重载、隐式转换和显式构造函数,c++,language-lawyer,implicit-conversion,default-constructor,C++,Language Lawyer,Implicit Conversion,Default Constructor,考虑以下小程序: #包括 甲级{ INTA; int b; 公众: 显式A()=默认值; A(int_A,int_b):A(_A),b(_b){ int f(常数A&A){return 0;} intf(std::vector a){return 1;} }; int g(常数A&A){return 2;} int g(std::vector a){return 3;} int main(){ A(1,2); //a.f({});//根据gcc不明确 g({});//根据gcc不明确 返回0;

考虑以下小程序:

#包括
甲级{
INTA;
int b;
公众:
显式A()=默认值;
A(int_A,int_b):A(_A),b(_b){
int f(常数A&A){return 0;}
intf(std::vector a){return 1;}
};
int g(常数A&A){return 2;}
int g(std::vector a){return 3;}
int main(){
A(1,2);
//a.f({});//根据gcc不明确
g({});//根据gcc不明确
返回0;
}
GCC10.2拒绝编译:它说对
g({})
a.f({})
的调用是不明确的。当啷,毫无怨言地编译这个

在我看来,重载解析中不应该考虑
g(const A&)
,因为不允许从无参数进行隐式转换:
A::A()
标记为显式

我不相信这不是我的错,无论如何,我想找到一个解决办法

是否有另一个默认生成的构造函数可能是我的问题的根源

你可以在桌子上试试


这引起了我的注意。它的答案告诉我们哪个编译器是正确的:它是GCC。但它并没有告诉我们如何使用这些重载规则获得所需的行为。

你说得对,它看起来像一个bug。下面注释掉的行未能编译,原因是不应存在歧义

使用std::initializer\u list为您找到了一个解决方法:

#include <fmt/core.h>
#include <vector>

class A {
  int a;
  int b;

 public:
  explicit A() = default;
  A(int _a, int _b) : a(_a), b(_b) {fmt::print("Aab\n");}

  void f(const A& a) { fmt::print("A\n"); }
  void f(std::vector<int> a) { fmt::print("vector\n"); }
  void f(std::initializer_list<int> l) {
      return f(std::vector<int>(l));
  }
};
void g(const A& a) { fmt::print("A\n"); }
void g(std::vector<int> a) { fmt::print("vector\n"); }
void g(std::initializer_list<int> a) {return g(std::vector<int>(a)); }

int main() {
  A a(1,2);
  A a2 = A();
  //A a3 = {};
  a.f({});
  g({});
  return 0;
}
#包括
#包括
甲级{
INTA;
int b;
公众:
显式A()=默认值;
A(int_A,int_b):A(_A),b(_b){fmt::print(“Aab\n”);}
void f(const A&A){fmt::print(“A\n”);}
void f(std::vector a){fmt::print(“vector\n”);}
无效f(标准::初始值设定项\u列表l){
返回f(std::vector(l));
}
};
void g(const A&A){fmt::print(“A\n”);}
void g(std::vector a){fmt::print(“vector\n”);}
void g(std::initializer_list a){返回g(std::vector(a));}
int main(){
A(1,2);
a2=A();
//a3={};
a、 f({});
g({});
返回0;
}

我会在标题中将默认值改为显式,我不相信你是对的。在我看来,
{}
可能被允许使用显式构造函数,我不确定。这绝对不是一个隐含的转换…@yakdone。找到一个好的标题总是一件困难的事。有趣的是,如果你注释掉
std::vector
variant,gcc抱怨不能使用
a
的显式ctor。gcc是正确的-请参阅dup。谢谢标记。现在我想我有一个错误报告要提交。很好的发现-请分享错误链接,如果你报告一个。我想跟着走!看最新的编辑,似乎它毕竟不是一个GCC错误。好吧,我想我不得不向比亚恩让步!