gpt4 book ai didi

c++ - 统一处理左值和右值引用

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:14:40 25 4
gpt4 key购买 nike

我有两个相关的问题,都与如何统一处理左值和右值引用有关。

虚函数案例:

struct Foo {
Object m_object;

virtual void bar(SomeRefTypeOfObject object);
};

基本上,我想要实现的是拥有一个SomeRefTypeOfObject,它能够存储对Object 的左值和右值引用。 bar 是一个更大的函数,它将使用一个 m_object = object; 语句存储 object 的值(复制或移动操作,取决于关于存储引用的类型)。原因是我想避免使用两个 bar 函数(针对每个引用类型)。标准库中有没有什么可以方便有效地做到这一点,或者我是否必须为此推出自己的解决方案?如果我必须推出自己的解决方案,那么好的实现应该是什么样的?

模板函数案例:

struct Foo {
Object m_object;

template <...>
void bar(... object);
};

我想要一个 bar 模板,可以用任何类型的 Object 或其派生类/其他可以转换为 的对象调用>Object(就像如果 bar 是两个带有 const Object &Object && 参数的重载函数),但是用 只有 const Object &Object &&。所以,我不想为每个派生类型实例化 bar。最明确的方法是什么?我想我需要某种形式的 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), pnull(nullptr), 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]

关于c++ - 统一处理左值和右值引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46486176/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com