我厌倦了通过值传递所有对象,然后移动,或者在左值和右值上重载。我试图写一个类,如果右值被传递到构造函数中,它可以存储左值引用或普通对象。
下面是 backbone :
template<typename T>
class ref {
private:
T* m_ptr = nullptr;
std::optional<T> m_obj;
bool is_lvalue = true;
public:
ref(T& lvalue_ref) : m_ptr{ &lvalue_ref } {}
ref(T&& rvalue_ref) : m_obj{ std::move(rvalue_ref) }, is_lvalue{ false } {}
T& get() {
return (is_lvalue) ? *m_ptr : *m_obj;
}
};
字符串
我想把这个类和像void foo(ref<bar> r) {}
这样的函数一起使用,所以任何接受ref<T>
的函数都不会做任何拷贝。不幸的是,每当你得到值的时候,你都必须检查一个引用/对象是否被存储,std::optional
默认构造它的对象,即使我们存储的是一个左值,我们也要为此付出代价。有没有可能创建一个类,它存储一个左值引用,或者一个对象,仍然能够有一个函数,它的值为ref<T>
,能够把T的左值和右值都绑定到它上面吗?
1条答案
按热度按时间2vuwiymt1#
我先引用我的评论,这样每个人都可以全面了解我的...观点。
我同意@JaMiT这是一个XY problem。事实上,这个问题的特点是一个可能的解决方案的框架,一个没有很好地定义的问题:你写 “我厌倦了通过值传递所有对象,然后移动,或者重载左值和右值”。给出一个让你认为你需要一个问题解决方案的代码例子。你重载右值引用和左值引用的上下文是通用上下文吗?或者你指的是接受具体值的函数?这些方面都没有在Q中解释。
但我仍然认为可以尝试一些猜测。
从
我厌倦了通过值传递所有对象,然后移动,或者重载左值和右值。
和
我想将这个类与void
foo(ref<bar> r) {}
这样的函数一起使用,所以任何接受ref<T>
的函数都不会进行任何复制。我假设你有很多函数接受args的值,和/或很多函数为
&
和&&
重载,在任何一种情况下,args的类型都是具体的(否则,如果这些函数是模板化的,我希望至少在你的问题主体中提到一个转发引用)。为了避免复制,我认为你会去(或者你已经去了)这样的解决方案,这是重复的几个函数,在那里你复制的不仅仅是头中的接口,
字符串
还包括实现文件中的业务逻辑:
型
典型的客户端代码如下所示,
型
如果是这样的话,一个解决方案可能是只对函数进行模板化,然后在cpp文件中实现它们,**连同你需要的两个显式示例化 *:
的字符串
请注意,我的玩具示例在两种情况下具有相同的长度,但两者之间存在一些差异。在我提出的解决方案中,
std::forward<T>
传递给其他函数,而在“手动”重载的情况下,你必须在一个重载中写入std::move
,而在另一个重载中什么都不写;Bar
更简单的类型来测试foo
,只需为BarForTests
模拟类型示例化foo
。