首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >存储引用的C++优化破坏代码

存储引用的C++优化破坏代码
EN

Stack Overflow用户
提问于 2020-11-24 16:43:30
回答 1查看 61关注 0票数 0

我的代码遇到了一个问题,在没有优化的情况下可以正常工作,但是当启用优化时就会中断。经过大量的调查,我发现了代码中断的点。看来这个问题与我使用参考资料有关。

我有一个简单的课程如下:

代码语言:javascript
复制
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)存储为引用,因为对于我的应用程序来说,这个对象充当已经存在的变量的包装器,并且对象的生存期仅限于变量本身。

下面是我如何使用它的一个例子:

代码语言:javascript
复制
void myFunction(int a, bool b) {
    DoubleValueEvent<int,bool> e(a,b);
    
    //This functions uses e but never stores it
    foo(&e);
}

这样做非常有效,避免了不必要的数据处理。但是,在以下情况下,它会中断:

代码语言:javascript
复制
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构造函数并没有正确地“移动”转换()中的临时返回值,因此编译器正在优化这个值,但我不确定。

有什么建议吗?

谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-11-24 16:52:24

您在正确的轨道上:您的rvalue引用-接受构造函数没有正确地“移动”该值。事实上,在移动的意义上,它根本没有移动它--从它构造一个值。

这很有道理。您还没有定义将其移动到的位置。您的类包含几个引用,但是没有地方存储它们。在这一行代码完成之后,int属于什么?

似乎您正在尝试从最重要的康斯特的某些变体中获益,在该变体中,绑定到const引用的临时生存期在对象的生存期内保持不变。但这只适用于本地范围的引用,而不适用于类中的引用。

正如您已经说过的,“这个对象充当已经存在的变量的包装器”。但在有问题的情况下,它没有任何变量可供包装,只是暂时到期。

类可以存储传递给其构造函数的lvalue引用,但是您需要非常非常小心地处理它。类存储传递给其构造函数的rvalue引用(包括将它们作为lvalue引用存储)永远都是不可能的。事实上,它是一个rvalue引用,这意味着它即将消失。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64990976

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档