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

如何在C++中编写函数g()避免重复解析返回类型且不使用推导返回类型

问题需求

我们需要编写函数g()的声明,既要避免使用返回类型推导(包括受约束的返回类型),又要确保c1或f()的返回类型只被解析一次(哪怕是在未求值上下文中),同时不能牺牲代码清晰度(本简化示例未能充分体现清晰度的重要性)。

原代码示例:

template<typename T>
struct s { using t = T; };

inline constexpr auto c1 = []{ return s<class a>{}; };
inline constexpr auto c2 = []{ return s<class b>{}; };

template<typename T>
constexpr auto f(s<T> (*c)()) -> s<T>
{ return c(); }

static_assert(sizeof(f(+c2)));
static_assert(sizeof(f(+c1)));

constexpr auto g() -> s<typename> // 理想写法但不被支持
{ return f(+c1); }
constexpr auto g() -> s<decltype(c1())::t> // 会重复解析返回类型
{ return f(+c1); }
constexpr auto g() -> s<decltype(f(+c1))::t> // 会重复解析返回类型
{ return f(+c1); }

static_assert(sizeof(g()));

解决方案

可以通过提前定义类型别名缓存f(+c1)的返回类型,确保只解析一次,同时满足显式指定返回类型的要求:

template<typename T>
struct s { using t = T; };

inline constexpr auto c1 = []{ return s<class a>{}; };
inline constexpr auto c2 = []{ return s<class b>{}; };

template<typename T>
constexpr auto f(s<T> (*c)()) -> s<T>
{ return c(); }

static_assert(sizeof(f(+c2)));
static_assert(sizeof(f(+c1)));

// 提前缓存返回类型,仅解析一次
using GReturnType = decltype(f(+c1));

// 显式复用缓存的类型作为返回类型
constexpr auto g() -> GReturnType
{ return f(+c1); }

static_assert(sizeof(g()));

说明

  • 定义GReturnType时仅对f(+c1)做一次类型推导,后续g()的返回类型直接复用该别名,彻底避免重复解析
  • 完全符合要求:未使用返回类型推导,且仅解析一次目标类型
  • 代码清晰度不受影响,类型别名的定义还能直观表达g()返回类型的来源

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 08:31:14