为什么我这里可以按值传递而不是按引用(C++)?

Why can I pass by value here but not by reference (C++)?

我这里有一个有趣的困境,如果我按值将变量传递给函数,代码将编译,但如果我按引用传递它,代码将编译,我不确定为什么。在 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 进行更改)。但是,我不理解这种行为。 为什么会发生这种情况,在这种情况下是否有最佳的解决方法?

您的转换运算符:

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

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

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

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

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

但是,正如您所写 friend U;myClass 可以访问 y 的私有成员 data 并允许您执行以下操作:

get_name(y.data);