我遇到了以下奇怪的行为,我无法弄清楚发生了什么。
我有一个名为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;*/ }
神秘地说,这个实现(没有正文)有效。如果我注释掉这个定义,我会从编译器得到与operator - 错误不匹配。如果我不这样做,代码会编译警告缺少返回类型和未使用的变量&#39; v&#39; 。当我运行auto vec2 = -vec1
时,vec2
实际上包含一个有效的mvec_transf<..>
对象,该对象具有对vec1
的正确引用。
通过添加print语句,我可以确认实际调用了重载运算符。但是,对于print语句,vec2
包含对垃圾的引用,而不是对vec1
的引用。
这里发生了什么?
答案 0 :(得分:4)
你所拥有的只是未定义的行为。来自[stmt.return]:
离开函数末尾相当于没有值的返回;这会导致值返回函数中的未定义行为。
一种未定义的行为是神奇的工作代码。另一种类型是神奇地破坏你的硬盘代码。我不会依赖它神奇地工作很长时间。修复它!