为什么我这里可以按值传递而不是按引用(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);
我这里有一个有趣的困境,如果我按值将变量传递给函数,代码将编译,但如果我按引用传递它,代码将编译,我不确定为什么。在 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);