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

为什么我可以在这里按值传递,而不能按引用传递(C++)?,c++,class,templates,readonly,C++,Class,Templates,Readonly,我在这里遇到了一个有趣的困境,如果我通过值向函数传递变量,而不是通过引用传递变量,代码将编译,我不知道为什么。在标题h中: #include <iostream> #include <string> void get_name(std::string &name) { getline(std::cin, name); return; } template <class T, class U> class readonly { frien

我在这里遇到了一个有趣的困境,如果我通过值向函数传递变量,而不是通过引用传递变量,代码将编译,我不知道为什么。在标题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。这样做时,它将无法正确编译。问题在于,我通过引用将变量y传递给get_name函数。如果我更改函数,以通过值进行传递,则所有内容都会正确编译并按预期工作,但我显然不再对y进行更改。然而,我不理解这种行为。为什么会发生这种情况?在这种情况下有没有最佳的解决方法?

您的转换运算符:

operator const T&() const {return data;}
仅允许隐式转换为常量引用。这是有意义的,因为您对只读内容感兴趣。但是get_name需要对字符串的非常量引用。也就是说,get_name希望能够改变其输入。传入的类型无法转换为可变字符串引用,只能转换为常量字符串引用,因此无法编译

当您传递值时,它只是从const引用构造一个新字符串来传递到函数中,这很好


直观地说,一个名为get_name的函数可能需要一个常量引用,因为它不需要为了得到名称而改变输入。

正如Nir Friedman所解释的,get_name;Invokes隐式转换运算符,该运算符提供常量引用

但是,正如你给朋友U写的那样;,myClass可以访问y的私有成员数据,并允许您执行以下操作:

get_name(y.data);

只读类?有趣的这是不必要的,但同时可以自我解释。直观地说,名为get_name的函数应该使用返回值而不是输出参数。