You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 09:03:01