我有一个场景,我需要转换一个可以被 *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/