【问题标题】:Why can I pass by value here but not by reference (C++)?为什么我可以在这里通过值而不是通过引用(C++)?
【发布时间】:2017-07-04 03:11:55
【问题描述】:

我在这里遇到了一个有趣的困境,如果我通过值将变量传递给函数,但如果我通过引用传递它,代码将编译,我不知道为什么。在 header.h 中:

#include <iostream>
#include <string>

void get_name(std::string &name)
{
  getline(std::cin, name);
  return;
}

template <class T, class U>
class readonly
{
  friend U;
  private:
    T data;
    T& operator=(const T& arg) {data = arg; return data;}
  public:
    operator const T&() const {return data;}
};

class myClass
{
  private:
    typedef readonly<std::string, myClass> RO_string;

  public:
    RO_string y;

    void f()
    {
      get_name(y); // compile error
    }
};

main.cpp 实现文件只包含这个头文件,创建myClass 的实例,然后调用f()。这样做时,它将无法正确编译。问题在于我通过引用get_name 函数来传递变量y。如果我更改函数以便我通过值传递,那么一切都会正确编译并按预期工作(除非我显然不再对y 进行更改)。但是,我不理解这种行为。 为什么会发生这种情况?在这种情况下是否有解决此问题的最佳方法?

【问题讨论】:

  • 一个readonly 类?有趣的。这是不必要的,但同时也是不言自明的。

标签: c++ class templates readonly


【解决方案1】:

您的转换运算符:

operator const T&() const {return data;}

只允许隐式转换为 const 引用。这是有道理的,因为您有兴趣将某些内容设为只读。但是get_name 需要对字符串的非常量引用。也就是说,get_name 期望能够改变其输入。传入的类型无法转换为可变字符串引用,只能转换为常量字符串引用,因此无法编译。

当你按值传递时,它只是从 const 引用构造一个新的字符串传递给函数,这很好。

直观地说,一个名为 get_name 的函数可能应该采用 const 引用,因为它不应该仅仅为了获取名称而改变其输入。

【讨论】:

  • 直观地说,名为get_name 的函数应该使用返回值而不是输出参数。
【解决方案2】:

正如 Nir ​​Friedman 所解释的,get_name(y); 调用了隐式转换运算符,它为您提供了一个 const 引用。

但是,正如你写的friend U;myClass 可以访问y 的私人成员data 并允许你这样做:

get_name(y.data);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-04
    • 2011-02-04
    • 2019-08-06
    • 2015-08-22
    • 1970-01-01
    • 2015-03-24
    相关资源
    最近更新 更多