空身体的重载运算符神奇地工作
Posted
技术标签:
【中文标题】空身体的重载运算符神奇地工作【英文标题】:Overloaded operator with empty body magically works 【发布时间】:2015-09-04 12:28:25 【问题描述】:我遇到了以下奇怪的行为,我无法弄清楚发生了什么。
我有一个名为mvec
的向量类,它将实际值存储在一个数组中,还有一个类mvec_transf
,它是另一个向量的转换。它存储对另一个向量的引用,以及定义转换的一元函数。可以这样使用:
mvec<int, 3> vec1 1, 2, 3;
mvec_transf<mvec<int, 3>, std::negate<int>> vec2 vec1, std::negate<int>();
// `vec2` contains [-1 -2 -3]
我重载了operator-
,这样我就可以写auto vec2 = -vec1;
,这是我当前的实现:
template <class Vec_t>
mvec_transf<Vec_t, std::negate<typename Vec_t::elem_t>>
operator- (Vec_t& v)
/*std::out << "Hello from operator- " << std::endl;*/
不可思议的是,这个实现(没有主体)有效。如果我注释掉定义,我会从编译器收到 no match for operator- 错误。如果我不这样做,代码编译时会出现警告缺少返回类型和未使用的变量'v'。当我运行auto vec2 = -vec1
时,vec2
实际上包含一个有效的mvec_transf<..>
对象,该对象具有对vec1
的正确引用。
通过添加打印语句,我可以确认重载的操作符实际上被调用了。然而,对于 print 语句,vec2
包含对垃圾的引用,而不是对 vec1
的引用。
这是怎么回事?
【问题讨论】:
【参考方案1】:你所拥有的只是未定义的行为。来自[stmt.return]:
从函数的末尾流出相当于没有值的返回;这会在返回值的函数中导致未定义的行为。
一种未定义的行为是神奇的工作代码。另一种类型是神奇地破坏你的硬盘驱动器代码。我不会依靠它神奇地工作很长时间。修复它!
【讨论】:
别忘了nasal demons以上是关于空身体的重载运算符神奇地工作的主要内容,如果未能解决你的问题,请参考以下文章