GCC报构造函数歧义错误但MSVC正常,哪个符合C++17标准?
C++17标准下多默认构造函数的编译歧义问题
我尝试在类中定义多个可无参数调用的构造函数,编写了如下代码:
struct A { explicit A(int = 10); A()= default; }; A a = {}; // MSVC编译通过,但GCC和Clang编译失败
GCC给出的错误信息如下:
<source>:8:8: error: conversion from '<brace-enclosed initializer list>' to 'A' is ambiguous 8 | A a = {}; //msvc ok but gcc and clang fails here | ^ <source>:5:3: note: candidate: 'constexpr A::A()' 5 | A()= default; | ^ <source>:4:12: note: candidate: 'A::A(int)' 4 | explicit A(int = 10);
根据C++17标准,GCC和Clang的行为是正确的,MSVC的编译通过不符合标准要求。
原因如下:
A a = {};属于拷贝列表初始化,此时会触发列表初始化的重载决议逻辑。- 由于初始化列表为空,且类
A没有接受std::initializer_list的构造函数,重载决议会将类的所有构造函数都纳入候选范围——包括显式声明的explicit A(int = 10)和默认构造函数A()。 - 这两个构造函数都可以被无参数调用:
A()直接匹配无参数调用,A(int = 10)依靠默认参数也能完成无参数调用。此时重载决议无法区分两者的优先级,因此产生调用歧义,编译器必须报错。
而MSVC的行为是不符合标准的,它可能在拷贝列表初始化中未将explicit构造函数纳入候选范围,从而只选择了默认构造函数,导致编译通过。
内容的提问来源于stack exchange,提问作者user20562802
相关产品推荐
相关产品推荐

