c – 统一处理左值和右值引用
我有两个相关的问题,都与如何统一处理左值和右值引用有关.
虚拟功能案例: struct Foo { Object m_object; virtual void bar(SomeRefTypeOfObject object); }; 基本上,我想要实现的是具有SomeRefTypeOfObject,它能够存储对Object的左值和右值引用. bar是一个更大的函数,它将使用一个m_object =对象; statement存储对象的值(复制或移动操作,具体取决于存储的引用的类型).原因是我想避免使用两个bar函数(对于每个引用类型).标准库中是否有任何可以方便有效地执行此操作的内容,或者我是否必须为此推出自己的解决方案?如果我必须推出自己的解决方案,那么良好的实现将如何? 模板功能案例: struct Foo { Object m_object; template <...> void bar(... object); }; 我想要一个条形模板,可以使用任何类型的Object或其派生类/其他对象调用它们,这些对象可以转换为Object(就像bar是两个带有const Object&和Object&&的过载函数;参数),但仅使用const Object& amp;和对象&& ;.所以,我不希望为每个派生类型实例化条形图.最明确的方法是什么?我想我在这里需要某种形式的SFINAE. 注意:m_object = object;赋值可以在由bar调用的函数中发生.因此,按值传递对象的解决方案不是最佳的,因为将进行不必要的复制/移动(可能存在移动并不像传递引用那样便宜的类型).此外,赋值可以以条件方式发生,因此只在叶子函数中传递对象而不是解决方案(因为它可以是运行时相关的,哪个函数执行实际赋值). 解决方法
类型擦除(或者可能是参考擦除可能是更好的术语)方法草图:
#include <iostream> #include <type_traits> #include <utility> struct Object { Object() { std::cout << "Object()" << std::endl; } Object(const Object &) { std::cout << "Object(const Object &)" << std::endl; } Object(Object &&) { std::cout << "Object(Object &&)" << std::endl; } Object &operator =(const Object &) { std::cout << "Object &operator =(const Object &)" << std::endl; return *this; } Object &operator =(Object &&) { std::cout << "Object &operator =(Object &&)" << std::endl; return *this; } }; template <class T> struct RLReferenceWrapper { bool is_rvalue; T *pnull; const T& cref; T&& rref; RLReferenceWrapper(T&& rref): is_rvalue(true),pnull(nullptr),cref(*pnull),rref(std::move(rref)) { } RLReferenceWrapper(const T& cref): is_rvalue(false),cref(cref),rref(std::move(*pnull)) { } template <class L> void Visit(L l) { if (is_rvalue) { l(std::move(rref)); } else { l(cref); } } }; struct Foo { Object m_object; virtual void bar(RLReferenceWrapper<Object> wrapper) { wrapper.Visit([this](auto&& ref){ m_object = std::forward<std::remove_reference_t<decltype(ref)>>(ref); }); } }; int main() { Foo f; f.bar(Object{}); Object o2; f.bar(o2); } 输出: Object() Object() Object &operator =(Object &&) Object() Object &operator =(const Object &) [live demo] (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |