c++ - 如何在模板化函数(c++)的返回类型中保留引用?
问题描述
我有一个名为 TypeHolder 的结构,它基本上是一个围绕类型 T 的薄包装器:
template <typename T>
struct TypeHolder {};
现在,我想创建一个函数,它接受任何类型的对象,如果对象是 TypeHolder(T 是 TypeHolder 的类型),则将该对象转换为 T。如果不是,该函数应该只保留对象的原始类型。
我试图定义这样的函数:
template <typename T>
auto castToObjIfTypeHolder(T obj, char) -> T; // This overload is called if T is not a TypeHolder
template <typename T>
auto castToObjIfTypeHolder(TypeHolder<T> obj, int) -> T; // This overload is called if T is a TypeHolder
// You call the function like so: castToObjIfTypeHolder(obj, 0), which will prefer the second overload by default (as int is a better match for 0 than char).
// However, when i called the function with an int& the return type is int but I would like it to be int& instead.
重载决议非常有效,每次都会调用正确的函数。但是,当调用第一个重载时,来自原始类型 T 的任何引用都将被剥离。例如,如果我传递一个类型为 的对象int&
,则返回类型为int
。同样,如果我传递一个类型为 的对象int&&
,则返回类型为int
。
我想保留引用,即当我传递一个类型的对象时int&
,返回类型应该是int&
.
为什么第一个重载会删除引用以及如何保留引用?
解决方案
如果您只想检索类型,则可以使用结构和(部分)专业化:
template <typename T>
struct UnderlyingTypeIfTypeHolder
{
using type = T;
};
template <typename T>
struct UnderlyingTypeIfTypeHolder<TypeHolder<T>>
{
using type = T;
};
如果你想调度代码,我会选择 C++17 if constexpr
:
template <typename T>
decltype(auto) castToObjIfTypeHolder(T&& obj)
{
if constexpr (is_TypeHolder_v<std::decay_t<T>>) {
return std::decay_t<T>::type{};
} else {
return std::forward<T>(obj);
}
}
注意:特征is_TypeHolder
可以按照上述方法完成。
推荐阅读
- php - Nginx 在提供 PHP 脚本时返回“未指定输入文件”
- google-apps-script - 谷歌表格的最后一行编辑
- reactjs - K8s 中 ReactJS 容器的 CPU 利用率线性增长
- r - 根据捕获日期和体重计算动物年龄
- javascript - 不确定如何为有条件渲染的 ReactJS 组件编写测试用例
- javascript - 如何使用单个 useState 钩子实现反应倒计时?
- vuetify.js - 为什么 vue-cli 明白我已经安装了 vue-cli-plugin-vuetify 和 vuetify-loader?
- python - 如何在 Django 中的另一个应用程序的视图中使用我的 base.html 模板?
- database - 在颤振中向sqlite添加新数据时遇到此错误
- c# - 如果从 UI 线程以外的线程调用 BindingOperations.EnableCollectionSynchronization 会发生什么?