c++ 有没有可能写一个类来专门存储左值引用或对象?

eqqqjvef  于 2023-11-19  发布在  其他
关注(0)|答案(1)|浏览(111)

我厌倦了通过值传递所有对象,然后移动,或者在左值和右值上重载。我试图写一个类,如果右值被传递到构造函数中,它可以存储左值引用或普通对象。
下面是 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的左值和右值都绑定到它上面吗?

2vuwiymt

2vuwiymt1#

我先引用我的评论,这样每个人都可以全面了解我的...观点。
我同意@JaMiT这是一个XY problem。事实上,这个问题的特点是一个可能的解决方案的框架,一个没有很好地定义的问题:你写 “我厌倦了通过值传递所有对象,然后移动,或者重载左值和右值”。给出一个让你认为你需要一个问题解决方案的代码例子。你重载右值引用和左值引用的上下文是通用上下文吗?或者你指的是接受具体值的函数?这些方面都没有在Q中解释。
但我仍然认为可以尝试一些猜测。

我厌倦了通过值传递所有对象,然后移动,或者重载左值和右值。

我想将这个类与void foo(ref<bar> r) {}这样的函数一起使用,所以任何接受ref<T>的函数都不会进行任何复制。
我假设你有很多函数接受args的值,和/或很多函数为&&&重载,在任何一种情况下,args的类型都是具体的(否则,如果这些函数是模板化的,我希望至少在你的问题主体中提到一个转发引用)。
为了避免复制,我认为你会去(或者你已经去了)这样的解决方案,这是重复的几个函数,在那里你复制的不仅仅是头中的接口,

// foo.hpp
#pragma once
#include "Bar.hpp"
void foo(Bar&);
void foo(Bar&&);

字符串
还包括实现文件中的业务逻辑:

// foo.cpp
#include "Bar.hpp"
void foo(Bar& x) {
    business_logic(x);
}
void foo(Bar&&) {
    business_logic(std::move(x));
}


典型的客户端代码如下所示,

// main.cpp
#include "foo.hpp"
#include "Bar.hpp"
int main()
{
    foo(Bar{3});
    Bar x{3};
    foo(x);
}


如果是这样的话,一个解决方案可能是只对函数进行模板化,然后在cpp文件中实现它们,**连同你需要的两个显式示例化 *:

// foo.hpp
#pragma once
template<typename T>
void foo(T&&);
// foo.cpp
#include "Bar.hpp"
template<typename T>
void foo(T&& t) {
    business_logic(std::forward<T>(t));
}
template void foo(Bar&);
template void foo(Bar&&);

的字符串
请注意,我的玩具示例在两种情况下具有相同的长度,但两者之间存在一些差异。在我提出的解决方案中,

  • 右值和左值只有一个共享的实现,所以你不会重复业务逻辑;
  • 你可以只把参数std::forward<T>传递给其他函数,而在“手动”重载的情况下,你必须在一个重载中写入std::move,而在另一个重载中什么都不写;
  • 测试的好处是,可以使用比Bar更简单的类型来测试foo,只需为BarForTests模拟类型示例化foo

相关问题