CRTP技术:如何推导派生类成员类型作为基类方法返回类型?
解决CRTP基类方法返回类型依赖派生类成员类型的问题
针对你提出的CRTP场景,有几种简洁的方式可以替换???,让基类sum_a_b的sum()方法返回类型自动匹配派生类中a和b的类型:
方案1:使用C++14的decltype(auto)(最简洁)
decltype(auto)会自动推导返回表达式的类型,完美适配你的需求:
template <typename C> struct sum_a_b { decltype(auto) sum() { return static_cast<C*>(this)->a + static_cast<C*>(this)->b; } }; template <typename T> struct a_b : sum_a_b<a_b<T>> { T a, b; };
这里decltype(auto)会直接推导出T类型(假设T的加法操作返回T类型),不需要额外的类型声明。
方案2:使用C++11的后置返回类型 + decltype + std::declval
如果你的项目还停留在C++11标准,这种方式同样可行:
#include <utility> // 引入std::declval template <typename C> struct sum_a_b { auto sum() -> decltype(std::declval<C>().a + std::declval<C>().b) { return static_cast<C*>(this)->a + static_cast<C*>(this)->b; } }; template <typename T> struct a_b : sum_a_b<a_b<T>> { T a, b; };
std::declval<C>()可以在不构造C对象的前提下,获取其成员的类型,配合decltype就能推导出a+b的结果类型,再通过后置返回类型指定给sum()方法。
方案3:显式声明派生类的类型别名(更显式)
如果你希望更清晰地暴露类型,可以让派生类定义一个类型别名,基类直接引用:
template <typename C> struct sum_a_b { typename C::value_type sum() { return static_cast<C*>(this)->a + static_cast<C*>(this)->b; } }; template <typename T> struct a_b : sum_a_b<a_b<T>> { using value_type = T; // 显式定义类型别名 T a, b; };
这种方式需要派生类额外添加value_type的别名,但好处是类型关系更直观。
内容的提问来源于stack exchange,提问作者463035818_is_not_an_ai
相关产品推荐
相关产品推荐

