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

MSVC中std::variant结合折叠表达式的static_assert失败问题

MSVC下is_of函数断言失败的原因分析

问题背景

以下代码实现了一个is_of函数,用于判断std::variant存储的值是否匹配指定类型,在GCC和Clang中运行正常,但在MSVC中标记为“Fails”的两个static_assert断言会失败,改用if constexpr展开折叠表达式后恢复正常:

#include <variant>

class A {};
class B {};

template<typename... Ts, typename Variant>
bool constexpr is_of(const Variant& variant)
{
  return std::visit(
      [](const auto& v) {
        using V = std::decay_t<decltype(v)>;
        return (std::is_same_v<V, Ts> || ...);
      },
      variant);
}


int main()
{
  using Variant = std::variant<A, B>;
  static_assert(is_of<A>(Variant{A{}}));
  static_assert(!is_of<B>(Variant{A{}}));

  static_assert(is_of<B>(Variant{B{}}));  // Fails
  static_assert(!is_of<A>(Variant{B{}}));  // Fails
  
  static_assert(!is_of<int>(Variant{A{}}));
  static_assert(!is_of<int>(Variant{B{}}));
  return 0;
}

失败原因

MSVC对泛型lambda内的折叠表达式处理存在实现差异:

  • 当std::visit实例化泛型lambda时,MSVC错误地将折叠表达式(std::is_same_v<V, Ts> || ...)的结果视为不依赖于lambda模板参数V的常量值,而非针对每个V类型单独计算结果。
  • 例如调用is_of<B>(Variant{B{}})时,MSVC可能错误复用了针对A类型计算的折叠表达式结果(false),而非针对B类型计算出正确的true,导致断言失败。

改用if constexpr后,编译期会明确根据当前V的类型选择分支,MSVC会为每个V类型生成独立的代码逻辑,从而正确计算匹配结果。

内容的提问来源于stack exchange,提问作者pasbi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 08:28:13