没有取消引用/解包对象的标准方法?
No standard way to dereference/unwrap objects?
在编写通用代码时,我经常发现自己处于这样的情况:我的 lib 用户提供的数据类型T
可能需要直接是某种具体类型,但同时又是指向类型。当 lib 中的泛型操作用于指向类型而不是指针时,这表示一个问题。有没有取消引用的标准方法?例如,像这样:
namespace std
{
template <typename T>
T& deref( T& t ){ return t; }
template <typename T>
T& deref( T* t ){ return *t; }
template <typename T>
T& deref( std::unique_ptr<T>& t ){ return *t; }
template <typename T>
T& deref( std::shared_ptr<T>& t ){ return *t; }
template <typename T>
T& deref( std::reference_wrapper<T>& t ){ return t.get(); }
}
这样我的代码将以用户决定的原始形式存储T
,但会对std::deref( t )
执行操作(例如operator==
或operator<<
(
据我所知,没有任何这样的功能。受这个答案的启发,自己写并不算太重(好吧,你自己已经做了,这个变体将扩展到任何提供operator*
的东西,不过(:
// first starting with some helper functions:
// return references as references!
template <typename T>
decltype(auto) doDeref(T& t, ...)
{
return t;
}
// if some custom operator* returns a temporary, we cannot bind to normal
// reference, so we'll accept as rvalue reference instead:
template <typename T>
decltype(auto) doDeref(T&& t, ...)
{
return std::move(t);
}
// specifically: anything that can be dereferenced:
template <typename T>
decltype(auto) doDeref(T& t, std::remove_reference<decltype(*t)>*)
// ^ to avoid trying to form pointer to reference
{
return doDeref(*t, nullptr);
}
// a temporary that might be dereferencable:
template <typename T>
decltype(auto) doDeref(T&& t, std::remove_reference<decltype(*t)>*)
{
return doDeref(*t, nullptr);
}
// reference wrapper; accept as const (!)
// be aware that return type still is non-const unless underlying
// type (i. e. T) is already const as well!
decltype(auto) doDeref(std::reference_wrapper<T> const& t)
{
return doDeref(t.get(), nullptr);
}
// and finally: the main functions calling the helpers:
template <typename T>
decltype(auto) deref(T& t)
{
return doDeref(t, nullptr);
}
// again to allow temporaries...
template <typename T>
decltype(auto) deref(T&& t)
{
return doDeref(std::move(t), nullptr);
}
奖励:对于不适合正常取消引用模式(如std::reference_wrapper
(的其他类型,这甚至是可扩展的,只需提供调用适当 getter 的另一个重载(如果类同时提供 const 和非 const getter,您可能需要为非 const 和 const 普通引用以及 rvalue 引用提供所有重载(。
相关文章:
- 使用带有C++对象和标准库容器的插件系统
- 没有取消引用/解包对象的标准方法?
- 标准::时间::d类型的挥发性对象
- 如何将来自 Boost.Python 的map_indexing_suite与自定义而不是标准对象一起使用?
- 无法重置 std::shared_ptr 标准::设置<>中的对象...为什么?
- C++标准:是否有结果对象?
- 在C++标准中记录对象的内存布局的哪个位置?
- 流对象来表示文件输入,然后是标准输入?
- 如何创建像标准库头一样的头,以便在不链接头中函数的所有对象文件的情况下编译程序?
- 列出 n 个对象的所有 k 排列的有效方法,同时满足特定标准
- 有没有办法为静态对象成员定义一个符合开关标准的常量?
- 哪个C 标准包括要添加到对象文件中的文件强制代码 /数据
- 提升::可选与标准::不可复制对象的可选
- 在标准布局对象中进行指针运算(例如,使用偏移量)时,我们是否需要使用 std::launder?
- 根据C++标准,int 变量是对象吗?
- 在C 中对二进制对象进行编码/解码的标准方法
- 从C 创建.NET标准对象
- 为非标准对象定义散列函数和相等函数
- 基对象和继承对象,用于将标准变量包装在C++中
- 如何在不注册对象的情况下访问标准项模型的数据?