我正在尝试在C ++中实现自定义引用。我想要实现的是引用,不需要在创建时设置。看起来像这样
template<typename T>
class myreference
{
public:
myreference() : data(), isset(false) { }
explicit myreference(const T& _data) : data(&_data), isset(true) { }
myreference<T>& operator=(T& t)
{
if (!isset)
{
isset= true;
data = &t;
}
else
*data = t;
return *this;
}
operator T() const { return *data; }
operator T&() { return *data; }
private:
T* data;
bool isset;
};
工作正常。我可以做到这一点,除了最后一句话。
myreference<int> myref;
int data = 7, test = 3;
myref = data; // reference is set
myref = test; // data is now 3
int& i = myref;
i = 4; // data is now 4
cout << myref; // implicit int conversion
myref = 42; // error C2679: binary '=' : no operator found which takes a right-hand operand of type 'int'
完整错误
error C2679: binary '=' : no operator found which takes a right-hand operand of type 'int' (or there is no acceptable conversion)
1> d:\...\main.cpp(33): could be 'myreference<int> &myreference<int>::operator =(const myreference<int> &)'
1> d:\...\main.cpp(16): or 'myreference<int> &myreference<int>::operator =(T &)'
1> with
1> [
1> T=int
1> ]
1> while trying to match the argument list 'myreference<int>, int'
我在网上搜索并发现了类似的错误(使用不同的运算符),结果是将运算符放在其类之外,但operator=
不可能一些(我相信很好)的理由。我的问题是,编译器抱怨什么?参数列表为myreference<int>, int
,我为T
定义了运算符,在本例中为int
。
答案 0 :(得分:1)
您实例化了myreference<int>
myreference<int> myref;
因此赋值运算符专用于参数类型int &
。但是,您试图识别可能绑定到常量引用的临时对象。因此赋值运算符必须专门用于参数类型const int &
。
因此,您需要定义另一个类型为myreference<const int>
的对象,该代码至少会被编译。例如
myreference<const int> myref1;
myref1 = 42;
但是在任何情况下代码都会有未定义的行为,因为在执行此赋值语句后将删除临时对象,并且数据成员数据将具有无效值。
通常这样的claases禁止使用临时对象来避免未定义的行为。
答案 1 :(得分:1)
您的问题大于编译器错误。编译器错误告诉您存在基本设计错误。
您的引用=
都充当引用重新绑定器(更改附加空引用的内容)和赋值(连接附加到的事物的值)。这些是基本不同的操作。
一个需要您可以稍后修改的长期值(重新绑定),另一个需要您可以读取的值(赋值)。
但是使用一个函数时,传递的参数必须是 - 并且这些类型不匹配。值可读是T const&
。可绑定值为T&
。
如果您将类型更改为T const&
,则重新绑定data = &t
将失败。如果您将42
之类的临时文件传递给=
,则会重新附加重新绑定,并在调用行的末尾变为无效。同样,如果您为其分配int const foo = 3;
。
你可以修复&#39;这有一个const_cast
,但只是抛出了检查窗口的类型:它隐藏了未定义的行为,而不是给你一个诊断。
另一方面,T&
参数不能绑定到42
临时值,也不能绑定到常量const int foo = 3
。在重新绑定的情况下这很好,但是使得任务变得毫无用处。
如果您有两个操作=(T const &)
和.rebind(T&)
,则问题就会消失。作为副作用,=
未设置时是未定义的行为。但在此之前基本上就是这样。
您的参考可能更好地称为“指针”。在这一点上。
答案 2 :(得分:0)
由于赋值运算符期望变量(在本例中为整数),因此不允许将其传递给某个值(42)。 所以使用像
这样的整数int x=42;
myref=x;
快乐的编码。
答案 3 :(得分:0)
myreference<T>& operator=(T& t)
myref = 42;
非const引用不能绑定到临时。您可以通过const引用将其更改为参数。
myreference<T>& operator=(const T& t)
此外,在代码中进行更改以使其工作。
data = &t; <<< Replace this
data = const_cast<T*>(&t); <<< with this.