通过正确引用混淆的c ++函数
c++ function that pass by right reference confusion
我正在查看 std::move 函数的源代码。它所做的是删除引用并添加正确的引用(&&)。
/**
* @brief Convert a value to an rvalue.
* @param __t A thing of arbitrary type.
* @return The parameter cast to an rvalue-reference to allow moving it.
*/
template<typename _Tp>
constexpr typename std::remove_reference<_Tp>::type&&
move(_Tp&& __t) noexcept
{ return static_cast<typename std::remove_reference<_Tp>::type&&>(__t); }
所以,我想知道我是否可以做一个正确的引用并将其传递给函数?所以,这里是:
void f1(int&&) { std::cout << 1; }
void f1(int&) { std::cout << 2; }
int main() {
int&& x = 1;
f1(static_cast<decltype(x)>(x));
f1(static_cast<int&&>(x));
f1(x);
}
并且,输出:112
我发现 x 是 int&& 类型,因为前两个 f1 做同样的事情。但是,第三个呢?这不是一个 int&& 吗?为什么我必须 static_cast 它才能像正确的参考一样使用它?
我知道 "c++ templates complete guide" 中有一个蛤蜊是:
The fact that move semantics is not automatically passed through is intentional
and important. If it weren’t, we would lose the value of a movable object the first time we use it in a function.
我仍然很好奇为什么它们 select 即使它们具有相同的类型,但在编译时的功能却不同?
你混淆了类型和 value categories,它们是不同的东西。
作为命名变量,x
的值类别是左值,(它的类型是int&&
。)左值可以绑定到左值引用,但不能绑定到右值-参考。因此给定 f1(x);
,f1(int&)
将被 selected.
要调用 f1(int&&)
,您需要将其转换为右值。第一个和第二个 select f1(int&&)
因为显式转换会生成右值表达式(更准确地说是 xvalue 表达式);可以绑定到右值引用。 std::move
也以类似的方式工作。
The following expressions are xvalue expressions:
- a function call or an overloaded operator expression, whose return type is rvalue reference to object, such as
std::move(x)
;
- ...
- a cast expression to rvalue reference to object type, such as
static_cast<char&&>(x)
;
- ...
我正在查看 std::move 函数的源代码。它所做的是删除引用并添加正确的引用(&&)。
/**
* @brief Convert a value to an rvalue.
* @param __t A thing of arbitrary type.
* @return The parameter cast to an rvalue-reference to allow moving it.
*/
template<typename _Tp>
constexpr typename std::remove_reference<_Tp>::type&&
move(_Tp&& __t) noexcept
{ return static_cast<typename std::remove_reference<_Tp>::type&&>(__t); }
所以,我想知道我是否可以做一个正确的引用并将其传递给函数?所以,这里是:
void f1(int&&) { std::cout << 1; }
void f1(int&) { std::cout << 2; }
int main() {
int&& x = 1;
f1(static_cast<decltype(x)>(x));
f1(static_cast<int&&>(x));
f1(x);
}
并且,输出:112
我发现 x 是 int&& 类型,因为前两个 f1 做同样的事情。但是,第三个呢?这不是一个 int&& 吗?为什么我必须 static_cast 它才能像正确的参考一样使用它? 我知道 "c++ templates complete guide" 中有一个蛤蜊是:
The fact that move semantics is not automatically passed through is intentional and important. If it weren’t, we would lose the value of a movable object the first time we use it in a function.
我仍然很好奇为什么它们 select 即使它们具有相同的类型,但在编译时的功能却不同?
你混淆了类型和 value categories,它们是不同的东西。
作为命名变量,x
的值类别是左值,(它的类型是int&&
。)左值可以绑定到左值引用,但不能绑定到右值-参考。因此给定 f1(x);
,f1(int&)
将被 selected.
要调用 f1(int&&)
,您需要将其转换为右值。第一个和第二个 select f1(int&&)
因为显式转换会生成右值表达式(更准确地说是 xvalue 表达式);可以绑定到右值引用。 std::move
也以类似的方式工作。
The following expressions are xvalue expressions:
- a function call or an overloaded operator expression, whose return type is rvalue reference to object, such as
std::move(x)
;- ...
- a cast expression to rvalue reference to object type, such as
static_cast<char&&>(x)
;- ...