"auto v = f()"和"auto&& v = f()"有什么区别?
What's the difference between "auto v = f()" and "auto&& v = f()"?
#include <vector>
using namespace std;
vector<int> f()
{
return{};
}
// Update: Below is not compilable
void g(vector<int>)
{}
// Update: Below is the my initial intent.
/*
void g(const vector<int>&)
{}
*/
void g(vector<int>&&)
{}
int main()
{
auto v1 = f();
auto&& v2 = f();
g(forward<vector<int>>(v1));
g(forward<vector<int>>(v2));
}
C 11保证g(forward<vector<int>>(v1))
会致电f(vector<int>)
或f(const vector<int>&)
,并且g(forward<vector<int>>(v2))
将调用f(vector<int>&&)
?
区别在于 v1
是向量,而 v2
是对向量的rvalue引用。
超载g
您的完成方式是一个非常糟糕的主意。如果该参数是CV Unqualified Rvalue,则该调用将是模棱两可的,因为两个g
的C可以接受具有身份转换序列的RVALUE。但是,可以接受一个过载T&
,另一个超负荷以T&&
。
如果要转发f()
的值类别,请不要像完成v1
一样复制/移动它。这会破坏价值类别信息。 v1
将永远是lvalue。
此外,您无法正确使用std::forward
。v1
和v2
都将被施放为rvalue参考,在这种情况下,在超载分辨率下的行为。
这是std::forward
的适当用法:
void g(vector<int>&);
void g(vector<int>&&);
int main() {
auto&& v1 = function_returning_lvalue_vector();
auto&& v2 = function_returning_rvalue_vector();
g(forward<decltype(v1)>(v1)); // calls lvalue overload
g(forward<decltype(v2)>(v2)); // calls rvalue overload
}
有一个与返回函数关联的对象,称为返回值。f()
的返回值是vector<int>
。
在C 11和C 14中,其中f()
按值返回:
-
auto v1 = f();
使用复制/移动构造函数初始化了vector<int>
,该 CC_23将从返回值中称为v1
。这是复制省略上下文。 -
auto&& v2 = f();
将名称v2
指定为返回值,并且返回值的寿命已延长。
如果编译器确实实现了复制率,则这两个代码具有相同的效果。从C 17中,带有所谓的"保证复制责任",这两个代码将相同。
由"相同",除了decltype(identifier)
的结果外,我的意思是相同的。
您的两个g
调用之间没有区别。在这两种情况下,该参数都是std::vector
型的LVALUE。表达式 v1
和 v2
不要"记住"它们是否最初是返回值对象。
std::forward
仅在给定一个模板参数时才是有用的,该模板参数是完美转发扣除的结果(因此,可能是参考类型)。
建议使用decltype
。decltype(identifier)
是一种特殊情况,确实回想起标识符在应用auto
扣除后如何声明。
-
decltype(v1)
是vector<int>
-
decltype(v2)
是vector<int> &&
,但是现在我们有:
-
std::forward<decltype(v1)>
是vector<int> &&
-
std::forward<decltype(v2)>
是vector<int> &&
因此,您仍然不会区分两种不同形式的g
。
实际上,如评论中所述,根本不可能致电g
。每个电话都会模棱两可。在过载分辨率中,直接参考绑定是一种身份转换。类型T
的XVALUE参数是参数T
的平等匹配,与T&&
一样。(同样,类型T
的LVALUE参数将是参数T
的平等匹配。
可以超载g
具有LVALUE与RVALUE重载。但是您也需要更改v1
的初始化:
void g(vector<int> const &) {}
void g(vector<int> &&) {}
// ...
auto const& v1 = f();
auto&& v2 = f();
g( std::forward<decltype(v1)>(v1) );
g( std::forward<decltype(v2)>(v2) );
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- int(c) 和 c-'0' 之间的区别。C++
- 向量 <int> a {N, 0} 和 int arr a[N] = {0} 的时间复杂度有什么区别
- C++ - "!pointer"和"pointer == nullptr"的区别?
- C++ 使用 assign 函数的字符串与直接使用 '=' 更改值的字符串之间的区别
- std::atomic和std::condition_variable wait,notify_*方法之间的区别
- 在 .h 文件中的类中声明静态变量和在.cpp文件中声明"global"变量有什么区别
- 在for循环中使用auto vs decltype(vec.size())来处理字符串的向量
- 我是C++编程的新手,这些代码之间有什么区别,我应该使用哪一个
- 在 const 函数中通过引用和指针返回之间的区别
- 我想知道长双倍和双倍之间的区别
- 返回常量对象引用 (getter) 和仅返回字符串有什么区别?
- 返回递归调用和仅递归调用的区别
- 如何在自定义类中启用'auto loops'?
- "auto x = vector<int>()"和"vector<int> x"有什么区别?
- "auto v = f()"和"auto&& v = f()"有什么区别?
- auto myFunc() 的区别或好处 -> int 和 int myFunc()
- C++0X 中的 auto 和 decltype 之间的区别
- decltype(auto)和decltype(return expr)作为返回类型有什么区别?
- foreach(int i.)与foreach(auto i.)的区别