【问题标题】:Are the values stored in std::pair<> by reference or by value?值是按引用还是按值存储在 std::pair<> 中的?
【发布时间】:2020-08-21 12:12:56
【问题描述】:

所以我有一个类 myClass 和两个私有变量,比如说 i,j 和一个类方法 myMethod 如下-

std::pair<int, int > myClass::myMethod(void)
{
    std::pair<int, int> Pair;
    this->i = 100;
    this->j = 50;
    Pair.first = this->i;
    Pair.second = this->j;
    return Pair;
}

我正在从另一个函数中调用如下方法-

std::pair<int, int> receivedPair = myClass.myMethod();

所以如果我编辑 receivedPair 让我们说

receivedPair.first = 200;

Class 变量i 也会变成200 吗? 我基本上需要通过引用几个串联函数来传递变量,以便更新相同的内存位置...... TIA

【问题讨论】:

  • 如果你能从代码中删除错别字会很好。 this.i ?不,那行不通

标签: c++ c++17 std-pair


【解决方案1】:

std::pair 的值是按值计算的。

在你的情况下,虽然你可以使用

std::pair<std::reference_wrapper<int>, std::reference_wrapper<int>>

作为类型。

参考:https://en.cppreference.com/w/cpp/utility/functional/reference_wrapper

【讨论】:

  • 显然,std::pair&lt;int&amp;, int&amp;&gt; 也可以。使用std::reference_wrapper有什么好处吗?
  • @ahmadPHreference_wrapper 是可重新安装的,这可能重要也可能不重要
  • 非常感谢@Bathsheba的回复,我浏览了文档,并没有明确提到它是否可以用于自定义类..我实际上需要通过参考传递OpenCV类和英特尔的真实感类
  • @AtharvaDubey:它也适用于自定义类。请注意,它真的包装了一个引用 - 而是封装了一个指针,并为您提供了一个隐式转换为引用的运算符。
  • @AtharvaDubey 如果您使用这种方法,您需要致电.get() 以便以后能够修改该对。例如,您必须致电receivedPair.first.get() = 200;。简单地使用“receivedPair.first = 200”会在以下行中引发错误:use of deleted function ‘std::reference_wrapper&lt;_Tp&gt;::reference_wrapper(_Tp&amp;&amp;) [with _Tp = int]’。我猜直接赋值是用来改变指针的,.get()是用来改变指向的内容的。
【解决方案2】:

std::pair,在你的具体情况下,无非就是这么多的话:

struct pair {
   int first;
   int second;
};

firstsecond,在您的 std::pair 中,是非引用类成员。 std::pair 的完整定义差不多

template<typename T1, typename T2> struct pair {
   T1 first;
   T2 second;
};

【讨论】:

  • 距离 template &lt;class T1, class T2&gt; struct refpair{T1&amp; first; T2&amp; second;}; 不到 100 万英里,尽管引用是分配任务的痛苦,所以可能麻烦大于它的价值。
  • 非常感谢,这很好解释。
  • @Bathsheba T1T2 可以只是 int&amp;;无需更改pair的def
  • @AsteroidsWithWings:我不太确定。例如,分配会发生不好的事情。可能高于我的工资等级。
  • “坏事”是编译失败,因为默认的赋值运算符被删除了。
【解决方案3】:

在您提供的示例中,值是按值存储的,因为您将类型声明为std::pair&lt;int, int&gt;。如果您希望通过引用存储这些值,您可以这样做:

std::pair<int&, int&> myClass::myMethod(void)
{
    this.i = 100;
    this.j = 50;
    std::pair<int&, int&> Pair(this.i, this.j);
    return Pair;
}

附:我只添加了这个答案,因为我认为std::reference_wrapper 的早期答案不会让您修改参考的内容!然后我发现你可以使用.get()修改内容。

【讨论】:

    【解决方案4】:

    std::pair 存储您告诉它的任何内容。您可以使用std::pair&lt;int&amp;,int&amp;&gt;。但是,作为成员的引用有一些缺点。复制、默认构造等等都是有问题的/不可能的。

    相对于使用一对引用,对一对的引用可能更容易:

    struct myClass {
        std::pair<int,int>& myMethod() {
            return data;
        }
        private:
        std::pair<int,int> data;
    };
    

    我声称如果你不能给成员起比ij 更好的名字,那么data.firstdata.second 一样好。另一方面,如果你能给出更好的名字,那就这样做吧:

    struct my_i_and_j {
        int some_meaningful_name;
        int another_meaningful_name;
    };
    
    struct myClass {
        my_i_and_j& myMethod() {
            return data;
        }
        private:
        i_and_j data;
    };
    

    但是,请注意,返回对私有数据的非常量引用会破坏封装。一旦调用者获得非常量引用,他们就可以直接修改私有数据,您可以/应该将其公开,以减少样板文件并提高清晰度。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-04
      相关资源
      最近更新 更多