MSVC C++17环境下使用字符串字面量初始化std::variant的std::string备选类型疑似存在Bug
MSVC C++17环境下使用字符串字面量初始化std::variant的std::string备选类型疑似存在Bug
没错,这确实是MSVC在C17编译模式下的一个已知兼容性问题,和C标准规定的行为不一致。
先来看测试代码:
#include <iostream> #include <string> #include <variant> void f(std::variant<bool, std::string> v) { if (std::holds_alternative<std::string>(v)) std::cout << "std::string\n"; if (std::holds_alternative<bool>(v)) std::cout << "bool\n"; } int main() { f("str"); }
不同编译环境的输出差异:
- 用MSVC的
cl.exe以/std:c++17编译时,程序输出:
bool
- 切换到
/std:c++20编译,或者用GCC、Clang等其他主流编译器以C++17及以上标准编译时,输出则符合预期:
std::string
问题原因:
这个差异的核心在于重载解析的优先级处理。字符串字面量"str"的类型是const char*,按照C17标准,当用它初始化std::variant<bool, std::string>时,应该优先选择通过用户定义转换(const char*隐式构造std::string)的备选类型,而非内置的指针转bool的转换。但MSVC在C17模式下错误地将指针转bool的优先级设得更高,导致variant被错误初始化为bool类型。
微软在C20模式下修复了这个行为,让它和标准以及其他编译器的表现对齐;而C17模式可能因为要兼容旧代码,暂时保留了这个不符合标准的行为。
备注:内容来源于stack exchange,提问作者3CEZVQ
相关产品推荐
相关产品推荐

