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

时间:2017-07-04 03:11:55

标签: c++ class templates readonly

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

2 个答案:

答案 0 :(得分:0)

您的转换运算符:

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

仅允许隐式转换为const引用。这是有道理的,因为你有兴趣做一些只读的东西。但get_name需要对字符串进行非const引用。也就是说,get_name期望能够改变其输入。传入的类型不能转换为可变字符串引用,只能转换为常量字符串引用,因此不会编译。

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

直观地说,一个名为get_name的函数应该采用const引用,因为它不需要改变它的输入只是为了获得名称。

答案 1 :(得分:0)

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

但是,在您撰写friend U;时,myClass可以访问data的私人成员y并允许您这样做:

get_name(y.data);