C++:我的右值在哪里
C++: Where is my rvalue?
请考虑以下代码:
#include <iostream>
template <class T>
class value_wrapper
{
public:
value_wrapper(T& pv) : v(pv) { std::cout<< "CONS.REF:" << pv << " AT:" << (void*)this << std::endl; }
value_wrapper(T&& pv) : v(pv) { std::cout<< "CONS.UNIREF:" << pv << " AT:" << (void*)this << std::endl; }
virtual ~value_wrapper() { std::cout<< "DEST:" << v << " AT:" << (void*)this << std::endl; }
value_wrapper(const value_wrapper& ov) : v(ov.v) { std::cout<< "CONS.COPY.REF:" << v << " AT:" << (void*)this << std::endl; }
value_wrapper(value_wrapper&& ov) : v(ov.v) { std::cout<< "CONS.COPY.UNIREF:" << v << " AT:" << (void*)this << std::endl; }
value_wrapper<T>& operator = (value_wrapper<T>&& ov)
{
std::cout<< "ASSI.UNIREF: OF " << v << " AT:" << (void*)this << " TO:" << ov.v << " AT:" <<(void*)&ov << " ADR.VAL:" << (void*)(&ov.v)<< std::endl;
v = ov.v;
return *this;
}
private:
template <typename V> friend value_wrapper<V> operator - (const value_wrapper<V> v1, const V& v2);
T& v;
};
template<typename T>
value_wrapper<T> operator - (const value_wrapper<T> v1, const T& v2)
{
T f = v1.v - v2;
value_wrapper<T> res(f);
std::cout << "MINUS: RESULT:" << res.v << " AT:" << (void*)&res << " ADR.VAL:" << &res.v << std::endl;
return res;
}
template<typename X>
value_wrapper<X> _ (X& a)
{
return value_wrapper<X>(a);
}
int main()
{
int a = 5;
std::cout << "BEFOR:" << a<< std::endl;
_(a) = _(a) - 1;
std::cout << "AFTER:" << a<< std::endl;
return 0;
}
以及他们的在线存在:
(坏的那个)http://cpp.sh/7yav
(好的)http://coliru.stacked-crooked.com/a/ea7363eaba68a336
而第一个输出:
BEFOR:5
CONS.REF:5 AT:0x761cebd52310
CONS.REF:4 AT:0x761cebd52320
MINUS: RESULT:4 AT:0x761cebd52320 ADR.VAL:0x761cebd522cc
CONS.REF:5 AT:0x761cebd52300
ASSI.UNIREF: OF 5 AT:0x761cebd52300 TO:0 AT:0x761cebd52320 ADR.VAL:0x761cebd522cc
DEST:0 AT:0x761cebd52300
DEST:27644 AT:0x761cebd52320
DEST:0 AT:0x761cebd52310
AFTER:0
第二个输出:
g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
BEFOR:5
CONS.REF:5 AT:0x7fffc51a5710
CONS.REF:4 AT:0x7fffc51a5720
MINUS: RESULT:4 AT:0x7fffc51a5720 ADR.VAL:0x7fffc51a56fc
CONS.REF:5 AT:0x7fffc51a5700
ASSI.UNIREF: OF 5 AT:0x7fffc51a5700 TO:4 AT:0x7fffc51a5720 ADR.VAL:0x7fffc51a56fc
DEST:4 AT:0x7fffc51a5700
DEST:4 AT:0x7fffc51a5720
DEST:4 AT:0x7fffc51a5710
AFTER:4
因此,问题来了:
从右值具有正确值的那一刻起,它发生了什么:
分钟:结果:4 AT:0x761cebd52320ADR。VAL:0x761cebd522cc
直到正确的值从同一地址消失:
ASSI.UNIREF:OF 5 AT:0x761cebd52300 TO:0 AT:0x761cebd52320ADR。VAL:0x761cebd522cc
看起来,我使用了与cpp.sh中的编译器相同的编译器(g++(Ubuntu 4.8.4-2ubuntu114.04)4.8.4),因为我得到了相同的结果。。。
这是一个编译器错误,还是只是我对标准右值应该如何工作的误解?
编辑:
I预期线路:
ASSI.UNIREF:OF 5 AT:0x761cebd52300 TO:0 AT:0x761cebd52320ADR。VAL:0x761cebd522cc
将:
ASSI.UNIREF:OF 5 AT:0x761cebd52300 TO:4AT:0x7761cebd52320ADR。VAL:0x761cebd522cc
即:值0为4,就像在其他打印输出中一样,因为它必须是正确的值,而不是0。
我认为这里有一个未定义的行为:
template<typename T>
value_wrapper<T> operator - (const value_wrapper<T> v1, const T& v2)
{
T f = v1.v - v2;
value_wrapper<T> res(f);
return res;
}
看到了吗?您返回的是一个value_wrapper<T>
,它封装了对T
的引用,而该引用引用了f
。Buff
是一个局部变量,所以您返回一个悬空引用,这就是UB。
相关文章:
- 询问在设计我的手臂模拟器功能表示格式1
- 在为我的基于文本的 RPG 游戏制作库存时遇到困难
- C ,二进制树的高度,而不是检查我的子树是否为空,而是在检查我的子树是否是叶子节点.抛出分割故障
- G++ 在编译我的 flex 和 bison 代码时无法识别我的 c++ 类
- 我在让我的代码输出整个链表时遇到问题.它只是输出我修改过的一些文本文件,而不是整个东西
- 如何在将我的 QT 应用程序交叉编译为 raspberry-pi3 时修复未知错误
- 我可以在获取我的"std::future"时执行并等待它吗?
- 我的 lambda 参数真的在阴影我的当地人吗?
- 卡在C++编写我的差异实用程序
- Gtk::在将我的gtkmm2移植到gtkmm3应用程序时,窗口显示并退出
- 什么在C++我的代码中不起作用
- 尝试在与我的 EXE 项目相同的解决方案中引用 DLL 项目时,出现错误"无法打开包含文件:"iostream"
- cout是在iostream中声明的,但它是在哪里定义的
- 在哪里我可以找到谷歌Szl(Sawzall)的资源
- c++标准和C语言在哪里说的是一样的:编译单元(.cpp文件)中的变量是按照声明的顺序初始化的
- 如何通过引用在Arduino我的类传递串行对象
- 是否有一种工具可以帮助理解谁将特定的参数传递给函数,以及该变量最初是在哪里创建的(在C/ c++中)
- 距离在哪里我只在乎文字
- 在升级我的mac后,编译mpic++不再有效
- *在哪里?我的文件和如何打开它