含std::variant的C++代码在MSVC可运行但GCC/Clang报错,求判定合规编译器
C++17代码跨编译器编译差异的标准符合性分析
我编写了一段C17代码,该代码在MSVC中可正常编译运行,但GCC和Clang会拒绝编译,希望明确哪款编译器的处理符合C标准。
测试代码
#include <variant> struct C { std::variant<bool> mem; C(std::variant<bool> p): mem(p) { } }; int main() { C c(1); // MSVC可编译通过,GCC和Clang报错 }
GCC报错信息
<source>: In function 'int main()': <source>:13:10: error: no matching function for call to 'C::C(int)' 13 | C c(1); // MSVC可编译通过,GCC和Clang报错 | ^ <source>:6:5: note: candidate: 'C::C(std::variant<bool>)' 6 | C(std::variant<bool> p): mem(p) | ^ <source>:6:26: note: no known conversion for argument 1 from 'int' to 'std::variant<bool>' 6 | C(std::variant<bool> p): mem(p) | ~~~~~~~~~~~~~~~~~~~^ <source>:3:8: note: candidate: 'constexpr C::C(const C&)' 3 | struct C | ^ <source>:3:8: note: no known conversion for argument 1 from 'int' to 'const C&' <source>:3:8: note: candidate: 'constexpr C::C(C&&)' <source>:3:8: note: no known conversion for argument 1 from 'int' to 'C&&' <source>:13:7: warning: unused variable 'c' [-Wunused-variable] 13 | C c(1); // MSVC可编译通过,GCC和Clang报错
结论与原因分析
GCC和Clang的处理符合C++标准,MSVC的行为不符合标准要求。
核心原因是std::variant<bool>的单参数构造函数在C标准中被定义为explicit。这意味着不能通过隐式转换将int类型转换为std::variant<bool>类型。代码中C c(1)试图依赖隐式转换完成参数类型匹配,这在标准C中是不允许的。
MSVC未正确实现该构造函数的explicit属性,允许了非标准的隐式转换,属于编译器的扩展行为。
修正后的代码
要让代码在所有编译器中兼容,需要显式构造std::variant<bool>:
#include <variant> struct C { std::variant<bool> mem; C(std::variant<bool> p): mem(p) { } }; int main() { // 显式构造std::variant<bool> C c(std::variant<bool>(1)); // 或者先将int转为bool再构造 // C c(static_cast<bool>(1)); }
内容的提问来源于stack exchange,提问作者user20562802
相关产品推荐
相关产品推荐

