我的代码遇到了一个问题,在没有优化的情况下可以正常工作,但是当启用优化时就会中断。经过大量的调查,我发现了代码中断的点。看来这个问题与我使用参考资料有关。
我有一个简单的课程如下:
template<typename T, typename U>
class DoubleValueEvent {
public:
DoubleValueEvent(const T& v0, const U& v1) : _v0(v0), _v1(v1) {}
//Move version of the constructor
DoubleValueEvent(const T&& v0, const U&& v1) : _v0(v0), _v1(v1) {}
inline const T& value0() const { return _v0; }
inline const U& value1() const { return _v1; }
private:
const T& _v0;
const U& _v1;
};我的值(v0和v1)存储为引用,因为对于我的应用程序来说,这个对象充当已经存在的变量的包装器,并且对象的生存期仅限于变量本身。
下面是我如何使用它的一个例子:
void myFunction(int a, bool b) {
DoubleValueEvent<int,bool> e(a,b);
//This functions uses e but never stores it
foo(&e);
}这样做非常有效,避免了不必要的数据处理。但是,在以下情况下,它会中断:
static inline int convert(int milliseconds) {
return milliseconds / 1000;
}
void mySecondFunction(int a, bool b) {
DoubleValueEvent<int,bool> e(convert(a),b);
//Breakpoint here shows the stored value for the int to be garbage
foo(&e);
}如果在对foo()的调用中放置一个断点,我可以看到存储在e中的引用值是一些垃圾值,而不是我所期望的值。
我推测正在发生的事情是我的DoubleValueEvent构造函数并没有正确地“移动”转换()中的临时返回值,因此编译器正在优化这个值,但我不确定。
有什么建议吗?
谢谢!
发布于 2020-11-24 16:52:24
您在正确的轨道上:您的rvalue引用-接受构造函数没有正确地“移动”该值。事实上,在移动的意义上,它根本没有移动它--从它构造一个值。
这很有道理。您还没有定义将其移动到的位置。您的类包含几个引用,但是没有地方存储它们。在这一行代码完成之后,int属于什么?
似乎您正在尝试从最重要的康斯特的某些变体中获益,在该变体中,绑定到const引用的临时生存期在对象的生存期内保持不变。但这只适用于本地范围的引用,而不适用于类中的引用。
正如您已经说过的,“这个对象充当已经存在的变量的包装器”。但在有问题的情况下,它没有任何变量可供包装,只是暂时到期。
类可以存储传递给其构造函数的lvalue引用,但是您需要非常非常小心地处理它。类存储传递给其构造函数的rvalue引用(包括将它们作为lvalue引用存储)永远都是不可能的。事实上,它是一个rvalue引用,这意味着它即将消失。
https://stackoverflow.com/questions/64990976
复制相似问题