c++ - std::reference_wrapper *this 周围

标签 c++ c++11

我有一个场景,我需要转换一个可以被 *this 链接的函数返回 std::optional<std::reference_wrapper<T>>而不是 T& (原因超出了这个问题的范围)。我使用 std::reference_wrapper 的原因是因为std::optional不能引用,至少在 C++11 中不能。但是,这不起作用,因为我似乎遇到了终身问题。这是一个最小的例子:

#include <iostream>
#include <functional>

struct test {
    std::reference_wrapper<test> foo() {
        val = 42;
        return *this;
    }

    test& foo2() {
        val = 50;
        return *this;
    }

    int val;
};

void bar(test t) {
    std::cout << std::move(t).val << "\n";
}

int main()
{
    auto f = test().foo();
    bar(f);
    auto g = test().foo2();
    bar(g);
}

这会输出 0 50而不是预期的 42 50 .如果我把它分成两个语句:

auto f = test();
auto f2 = f.foo();
bar(f2);

它按预期工作。使用调试器,我发现编译器正在优化一些表达式,并且 val未初始化,这让我认为我的代码中有未定义的行为。

我有未定义的行为吗?如果是这样,我该如何避免呢?

最佳答案

Do I have undefined behavior?

是的。 auto从用于初始化对象的表达式中推导出对象的类型。并且您使用 std::reference_wrapper<test> 类型的表达式初始化 f .临时test()f之后消失了被初始化,所以 f立即悬挂。

您可以像现在一样拆分声明,或者使用 std::references_wrappers的获取成员函数:

auto f = test().foo().get();

无论哪种方式,std::reference_wrapper<test>不是 C++ 支持的所有上下文中引用的替代品。代理对象永远不会。

关于c++ - std::reference_wrapper *this 周围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55040940/

相关文章:

c++ - 内联函数和复制构造函数

c++ - 从不与对象大小对齐的连续固定大小缓冲区解析对象的有效方法

c++ - 使用类型转换在 C++ 中返回二维数组

c++ - 在 WM_MOUSEMOVE 中拖动并绘制边框?

c++ - rand() 有某种数值限制吗?

c++ - 用 lambda 替换纯虚拟接口(interface)

c++:何时传递指针与返回对象

c++ - 用随机数填充多个 vector

c++ - 如果可能,取消对 C++ 类型指针的引用

C++11 可变参数模板 : return tuple from variable list of vectors