#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
进行更改)。但是,我不明白这种行为。 为什么会发生这种情况,并且在这种情况下是否有最佳解决方法?
答案 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);