模板类型推导是否包含const?如何用单个make_Holder自动推导含const类型
合并
make_Holder模板函数,自动推导含const限定的返回类型 当前可运行代码
template<typename T> class Holder { T& held; public: Holder(T& h) : held(h) {} friend std::ostream& operator<<(std::ostream& stream, Holder const& data) { return stream << "Held"; // 实际逻辑会从data.held.stuff取值,此处不影响问题核心 } }; template<typename T> Holder<T> make_Holder(T& toHold) {return Holder<T>(toHold);} template<typename T> Holder<T const> make_Holder(T const& toHold) {return Holder<T const>(toHold);} int main() { std::cout << make_Holder(12); int value = 12; std::cout << make_Holder(value); }
需求
将两个重载的make_Holder合并为单个模板函数,使其自动识别参数的const限定符,返回对应类型的Holder。
解决方案:使用转发引用自动推导类型
利用C++11引入的转发引用(T&&),让模板参数自动捕获传入值的cv限定符和值类别,再通过std::remove_reference_t剥离引用属性,得到用于Holder的目标类型。
修改后的完整代码:
#include <iostream> #include <type_traits> // 提供std::remove_reference_t工具 template<typename T> class Holder { T& held; public: Holder(T& h) : held(h) {} friend std::ostream& operator<<(std::ostream& stream, Holder const& data) { return stream << "Held"; } }; template<typename T> Holder<std::remove_reference_t<T>> make_Holder(T&& toHold) { return Holder<std::remove_reference_t<T>>(toHold); } int main() { std::cout << make_Holder(12); int value = 12; std::cout << make_Holder(value); const int const_value = 42; std::cout << make_Holder(const_value); // 自动返回Holder<const int> }
原理说明
- 转发引用
T&&会根据传入参数的实际类型推导T:- 传入非const左值(如
int value):T推导为int&,std::remove_reference_t<T>得到int,返回Holder<int>; - 传入const左值(如
const int const_value):T推导为const int&,std::remove_reference_t<T>得到const int,返回Holder<const int>; - 传入右值(如
12):T推导为int,std::remove_reference_t<T>得到int,返回Holder<int>,与原代码行为完全一致。
- 传入非const左值(如
这样仅需一个模板函数,即可覆盖所有原重载的场景,自动适配参数的const属性。
内容的提问来源于stack exchange,提问作者Loki Astari
相关产品推荐
相关产品推荐

