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

三元运算符作用于const char* const&与char*&的返回类型及编译器分歧咨询

三元运算符作用于const char* const&和char*&的返回类型解析

问题现象

给定以下代码:

#include <type_traits>

char* dummy;
const char* const& a = dummy;
      char*      & b = dummy;
using T = decltype(true ? a : b);
static_assert(std::is_same<const char* const&, T>::value); // Clang、MSVC(C++20) 通过
static_assert(std::is_same<const char*       , T>::value); // GCC、MSVC(C++17) 通过

不同编译器的行为存在分歧:

  • GCC 在所有C++版本中判定T为const char*
  • Clang 在所有C++版本中判定T为const char* const&
  • MSVC 在C17模式下返回const char*,C20模式下返回const char* const&

标准规则解析

分歧的根源在于C17与C20对条件表达式(三元运算符)的类型推导规则差异:

C++17及更早版本

根据C++17标准的[expr.cond]条款:

  1. 首先剥离两个操作数的引用属性,得到底层类型:a的表达式类型为const char* const(左值),b的表达式类型为char*(左值)。
  2. 推导两者的公共类型为const char*——char*可隐式转换为const char*,而const char* const的顶层const会被忽略在类型转换中。
  3. 由于公共类型const char*并非引用类型,条件表达式会将两个操作数转换为该类型的纯右值(prvalue),最终decltype推导的结果为值类型const char*。

C++20及更新版本

C++20对条件表达式的规则做了优化,当两个操作数均为左值,且其中一个可隐式转换为另一个的类型时:

  • char*可隐式转换为const char* const(先转换为const char*,再添加顶层const),此时条件表达式无需创建临时对象,直接返回左值引用类型const char* const&。
  • 因此decltype推导的结果为引用类型const char* const&。

结论

  • 在C++17及更早版本,符合标准的返回类型是const char*,GCC和MSVC(C++17)的行为正确。
  • 在C++20及更新版本,符合标准的返回类型是const char* const&,Clang和MSVC(C++20)的行为正确。

内容的提问来源于stack exchange,提问作者康桓瑋

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 01:32:17