【问题标题】:how can I copy vector in c++ by reference O(1)?如何通过引用 O(1) 在 C++ 中复制向量?
【发布时间】:2016-11-03 07:31:59
【问题描述】:

我想从参数中获得向量的类范围别名。

例如:

class Solution {
private:
     vector<int> b; // I want that &b = a, where a from function solve
     int f(int i) {
          // here I want to use vector<int> a, 
          // not passing it as a function argument every time
     }
public:
     int solve(vector<int>& a) {
          // here I want to do smth like b = a; which works for O(1)
     }
};

不幸的是,我不能只声明 vector&lt;int&gt; &amp;b; ,因为错误: declaration of reference variable 'b' requires an initializer

能否请您解释一下如何在 C++11/14 中做到这一点?

更新:我不能更改int solve(vector&lt;int&gt;&amp; a)的声明,这个接口是从外部提供的。

更新:我已将代码更改为更明确。看起来我不应该再这样做了,因为在答案和 cmets 中人们使用原始变量名。对不起,对 StackOverflow 没有太多经验。

【问题讨论】:

  • “爱丽丝”是什么意思?
  • 别名,抱歉,没戴眼镜没看到错字。
  • 那么如果有人在拨打solve 之前拨打f 会发生什么?
  • 也许f 是纯粹从solve 内部调用的。取自“每次都不将其作为函数参数传递”,并考虑到“我无法更改int solve(vector&lt;int&gt;&amp; _a) 的声明,即从外部提供的接口” - 我收集solve 是入口点并给出_a没有任何其他方式可用(已建议),f 似乎打算在solve 内使用,否则你怎么能在f 中收到a
  • 是的,你是对的。让我改一下代码。

标签: c++ c++11 pointers vector reference


【解决方案1】:

也许是这个?

class Solution {
public:
     vector<int> a;
     int maxCoins(const vector<int>& _a) { // const because copying
          a.assign( _a.begin(), _a.end() );
     }
};

但要知道,如果您想要引用原始 vector&lt;int&gt; 而不是副本,您也可以这样做:

class Solution {
public:
     vector<int> & a;
     int maxCoins(vector<int>& _a) : a( _a ) {}
};

更新

这可能是最接近的。您不能重新初始化引用,但这正是指针的用例。

class Solution {
public:
     vector<int> * a;
     int f(int i) {
         a->size(); // can access indirectly
         (*a)[1]; // element access is slightly trickier
         vector<int> & _a = *a; // or can create a direct ref
         _a.size();
     }
     int solve(vector<int>& _a) {
         a = &_a; // store address to _a. a reference is like any local variable unless doing something funny
     }
};

更新 2 - 不使用指针

#include <functional>

class Solution {
public:
     // vector<int> a;
     typedef vector<int> datatype;
     datatype blankref;
     std::reference_wrapper<datatype> a = blankref;
     int f(int i) {
          vector<int> & _a = a;
     }
     int solve(vector<int>& _a) {
          a = std::ref(_a);
     }
};

您无法避免引用是一次性赋值的事实。必须使用初始化语法来分配类实例中的引用。要获得可重用的引用,您每次都需要有一个新初始化的对象。

为了帮助我们,感谢 cmets 中的建议,std::reference_wrapper&lt;T&gt; 类型可以保存引用实例。可以反复分配使用std::ref( _a )

老实说,指针在正确使用时并非不雅,imo。它归结为用例和你认为你需要的东西。性能方面,这可能不如指针(因为正在构造临时对象),但不能保证......它在任何情况下都应该执行类似的操作。

【讨论】:

  • 感谢您的回答! 1) 由于分配而适用于 O(n) 并且我无法更改 solve/maxCoins 函数的声明。 2) 编译器返回错误:only constructors take member initializers
  • 我认为你不能在 O(1) 中复制 vector&lt;&gt;。复制构造函数/赋值操作将单独复制每个元素(如果它们是类呢?),否则你有std::swap 来交换两个向量的内容。您的用例是什么,您需要在类中临时访问a(原始值)还是需要一个副本才能使用?如果您只需要访问,我建议您使用指针或 RAII / 令牌对象,否则您会因为 vector 的复制方式而陷入 O(n) 问题。
  • 是的,你是对的,我真的不需要向量的另一个副本,我需要参考副本,它实际上是同一块内存的别名。我明白,如何用指针来做,但是我正在寻找更优雅的方式。
  • 我已更改问题描述。抱歉标题不清楚。
  • 有一种方法可以避免使用指针,如果您认为它会有所帮助,可以说明如何使用,但它需要创建一个新的结构/类来完成它。值得? (有时)
猜你喜欢
  • 2021-04-19
  • 2020-06-18
  • 2014-09-18
  • 2021-12-28
  • 1970-01-01
  • 2011-09-25
  • 2014-06-07
  • 1970-01-01
  • 2017-05-16
相关资源
最近更新 更多