C++ C++;通过引用的析构函数

C++ C++;通过引用的析构函数,c++,move,c++17,move-semantics,C++,Move,C++17,Move Semantics,我想和大家分享一个我还没有解决的小问题,下面是代码(仅供测试): 我有几个问题: 1-为什么“test1”的dtor在其作用域结束之前被调用?我的意思是,代码甚至没有调用Execute方法。 2-如果“test1”的dtor是一个时态对象,为什么我看不到move-ctor中的日志,或者至少是一个编译器错误,因为它试图使用已删除的copy-ctor? 3.“test1”和“test2”有什么区别?我希望能够以任何方式调用Execute。 4-我错过了什么? 谢谢。这里有一个简单的版本演示了相同的问

我想和大家分享一个我还没有解决的小问题,下面是代码(仅供测试):

我有几个问题:
1-为什么“test1”的dtor在其作用域结束之前被调用?我的意思是,代码甚至没有调用
Execute
方法。
2-如果“test1”的dtor是一个时态对象,为什么我看不到
move-ctor
中的日志,或者至少是一个编译器错误,因为它试图使用已删除的
copy-ctor

3.“test1”和“test2”有什么区别?我希望能够以任何方式调用
Execute

4-我错过了什么?

谢谢。

这里有一个简单的版本演示了相同的问题:

struct X {
    X() = default;
    ~X() { std::cout << "dtor\n"; }
    X& self() { return *this; }
};

int main()
{
    X& x = X().self();
    std::cout << "here?\n";
}
现在,这将在
dtor
之前在此处打印

此外,没有可传递的生存期扩展。即使在最初的示例中,我们做到了:

X const& x = X().self();

我们仍然会得到一份悬而未决的推荐信

下面是一个简单的版本,演示了相同的问题:

struct X {
    X() = default;
    ~X() { std::cout << "dtor\n"; }
    X& self() { return *this; }
};

int main()
{
    X& x = X().self();
    std::cout << "here?\n";
}
现在,这将在
dtor
之前在此处打印

此外,没有可传递的生存期扩展。即使在最初的示例中,我们做到了:

X const& x = X().self();
我们仍然会得到一份悬而未决的推荐信

  • 在“test1”情况下,
    proc
    引用的对象是临时对象。它在创建它的完整表达式结束时超出范围,
    proc
    立即悬空。请注意,不会发生生存期扩展,原因有两个:a)生存期扩展仅与
    const
    左值引用和右值引用一起发生;b)生存期扩展仅与prvalue一起发生,而
    AppendParam
    返回的引用是左值
  • “test1”案例中的
    proc
    是一个引用,而不是一个对象。由于没有要移动或复制到的对象,因此不会进行移动或复制。引用绑定到由
    ProcedureCaller
    返回的临时对象,并且在下一次
    时超出范围
  • “test1”和“test2”之间的区别在于
    proc
    是“test1”中的一个引用,“test2”中的一个实际对象。如果您试图在“test2”案例中引用
    proc
    ,编译器会抱怨。只有
    const
    左值引用和右值引用可以绑定到prvalue(例如从函数返回的对象)。它在“test1”情况下工作的唯一原因是您通过返回左值引用的方法“清洗”了prvalue
  • 在“test1”情况下,
    proc
    引用的对象是临时对象。它在创建它的完整表达式结束时超出范围,
    proc
    立即悬空。请注意,不会发生生存期扩展,原因有两个:a)生存期扩展仅与
    const
    左值引用和右值引用一起发生;b)生存期扩展仅与prvalue一起发生,而
    AppendParam
    返回的引用是左值
  • “test1”案例中的
    proc
    是一个引用,而不是一个对象。由于没有要移动或复制到的对象,因此不会进行移动或复制。引用绑定到由
    ProcedureCaller
    返回的临时对象,并且在下一次
    时超出范围
  • “test1”和“test2”之间的区别在于
    proc
    是“test1”中的一个引用,“test2”中的一个实际对象。如果您试图在“test2”案例中引用
    proc
    ,编译器会抱怨。只有
    const
    左值引用和右值引用可以绑定到prvalue(例如从函数返回的对象)。它在“test1”情况下工作的唯一原因是您通过返回左值引用的方法“清洗”了prvalue

  • MVCE的魔力。介意我问一下你的话:“没有可传递的生存期扩展”,这是可传递的:
    xx1=X();常数X&X=x1.self()?MVCE的魔力。介意我问一下你的话:“没有可传递的生存期扩展”,这是可传递的:
    xx1=X();常数X&X=x1.self()
    X const& x = X().self();