std::move 和 static_cast<&&>

问题描述 投票:0回答:3

我理解对吗,如果我使用临时对象(如

std::move()
std::move(A())
)调用
std::move(int)
,它会返回对空闲内存的引用?

据我所知,如果

T&&
const T&
分配给右值或纯右值,它会在内存中创建一个对象并继续该对象的生命周期,同时引用不会被销毁?对引用的第二次赋值是否会延续对象的生命周期?

另外,如果我调用,例如:

int x; static_cast<int&&>(x)
,据我所知,这是一个 xvalue 语句(引用),但是对象的生命周期会发生什么?

int&& foo() {
    int n = 5;
    return std::move(n);
}

foo(); // can second rvalue reference continue life of object while exist ref to object?
int x = 0;

static_cast<int&&>(x); // what happens with life time of object? or
static_cast<const int&>(x);

std::move(0); // will it return free memory? or
std::move(std::string("hello, world!"));

我只是一个初学者,如果我有任何错误,如果你能纠正我,我将不胜感激。

c++ perfect-forwarding
3个回答
3
投票

对象的生命周期在对象创建时就确定了,此后就不再改变。 您无法对已存在的对象执行任何操作,从而导致其生命周期发生变化。

具体示例:

int&& foo() {
    int n = 5;
    return std::move(n);
}

foo
返回悬空引用。 当
n
返回时,
foo
的生命周期结束。 由于
foo
返回对
n
的引用,并且
n
的生命周期已结束,因此对
foo
返回的引用的任何读取或写入都将导致未定义的行为。

int x = 0;

static_cast<int&&>(x);
static_cast<const int&>(x);

这些类型转换什么也不做。 即使结果被分配给另一个变量,它们也不会对

x
的生命周期产生影响。

std::move(0);
std::move(std::string("hello, world!"));

这些都返回悬空引用。

0
std::string("hello, world!")
都创建临时对象。 引用生命周期扩展将它们的生命周期延长到
std::move
的参数的生命周期(因为它们在创建时立即绑定到该引用),但该参数的生命周期无论如何都比临时对象的生命周期短.


您的一些困惑似乎来自 C++ 所谓的“引用生命周期扩展”功能。 然而,这并不会延长现有对象的生命周期。 它只能延长对象的生命周期当它被创建时

如果临时对象在创建时立即绑定到引用,则该临时对象的生命周期将延长到引用的生命周期。

也就是说,参考寿命延长适用于以下所有情况:

// Here the string literal "Hello World" is converted to a to a temporary std::string // which has its lifetime extended to the lifetime of foo const std::string& foo = "Hello World"; // Here the return value of func is a temporary int object // which has its lifetime extended to that of i int func() { return 42; } const int& i = func();
参考寿命延长

不适用于在这些情况下:

// The temporary object created by the int literal 42 does not have // its lifetime extended to that of i because it is not bound to i // at the moment of its creation. const int& func() { return 42; } const int& i = func(); // The lifetime of the temporary std::string object created from the // string literal "some string" does not get extended to the lifetime // of f.member_ref because it is not bound to member_ref at the moment // of its creation struct Foo { const std::string& member_ref; Foo(const std::string& s) : member_ref(s) {} }; Foo f("some string");
    

1
投票
我认为混乱是因为

std::move()

没有移动任何东西。  这只是一个类型转换。  它根本不参与内存管理。

如果您的函数利用其参数是右值引用这一事实来执行不安全的操作(例如使参数无效),则编译器将保护您免于使用左值调用此类函数。 但是,如果您

想要使用左值调用这样的函数,并且知道您的变量可能会无效,则std::move()

会将其转换为右值,以便您可以调用该函数。

然而,是函数,而不是

std::move

,可能使参数无效。  
std::move
 只是让调用这样的函数成为可能。


0
投票
自动 isUseDAP = = { if (isActiveSoundOutUsePostProcessing == "使用" && mSoundModeType == "杜比全景声" && mSupportAtmosValue ==“开启”&& std::find(std::move(notUseDAPSoundOutput).begin(), std::move(notUseDAPSoundOutput).end(), activeSoundOutput) == notUseDAPSoundOutput.end()) 返回真; 返回假; };

© www.soinside.com 2019 - 2024. All rights reserved.