2017-04-18 51 views
-2

我有一个返回右值引用的函数。std :: vector :: push_back(T &&)在返回T &&的函数直接传递时创建T的默认构造值

auto function() -> int&& { 
    int x{10}; 
    std::cout << x << std::endl; // to check the value of x 
    return std::move(x); 
} 

现在,当我使用下面的代码:

std::cout << function() << std::endl; 
std::vector<int> v; 
v.push_back(function()); 
std::cout << v[0] << std::endl; 

这将导致下面的输出

10 
0 

看起来即使()函数返回一个右值引用,向量推回默认构造的int。

有趣的是,如果我有这样的代码:

auto x = function(); 
v.push_back(std::move(x)); 

这完美的作品。

看来,如果我只是从函数返回一个局部变量,那么RVO无论如何都会做一个复制elision。但由于我正在做一个明确的std :: move()我绊倒RVO导致返回一个临时变量。

现在,在v.push_back(function())中,我调用vector :: push_back(T & &)函数,结果是引用对temp变量的引用。在这种情况下,它总是趋向于0而不是垃圾(我猜测这是因为优化开启了)。但是,如果我尝试捕获函数的返回值,它可以工作,这大概是因为在返回值过程中创建的临时变量的值被复制到此局部变量。这看起来不像一个没有定义的行为的幸运儿。

回答

6

你的函数返回一个函数局部变量的引用,在任何人都可以使用它之前它被销毁。 (使用右值引用与使用左值引用相同,这与使用右值引用一样无效。)

+0

这有点混淆不清。当我使用类似'auto x = function()'的东西时,我可以看到x实际上保持了10的值,而不是默认构造的或垃圾。我预计,std :: move会传递本地对象的所有权,因此不会自动销毁。 – abhijit

+1

不,“x”的生命周期以函数结束。如果它有时似乎有效,那只是未定义的行为。 – aschepler

相关问题