如何在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
相关产品推荐
相关产品推荐

