为什么将右值绑定到 const 类型会使其成为左值?

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

这个问题可能没有最好的标题,但这里的代码将解释我想问的问题。

此代码运行并打印“左值”,但如果我从 MyPair 的第一种类型中删除

const
,它会给出预期的输出,即“右值”。我想知道
const
在这里扮演什么角色?

#include <iostream>
#include <utility>
#include <string>


using MyPair = std::pair<const std::string, int>;


void func(std::string&& str)
{
    std::cout << "rvalue" << std::endl;
}

void func(const std::string& str)
{
    std::cout << "lvalue" << std::endl;
}

template<typename T>
void func_forward(T&& p)
{
    func(std::forward<T>(p).first);
}

void test(MyPair&& p)
{
    func_forward(std::move(p));
}

int main()
{
    test({"hello", 3});
    return 0;
}
c++ rvalue-reference std-pair
1个回答
0
投票

在 C++ 中,右值是一个临时对象,在内存中没有稳定的位置。我们可以获取左值的地址,但不能获取右值的地址。右值可以绑定到右值引用 (

T&&
) 以延长其生命周期,也可以绑定到对
const
(
const T&
) 的左值引用,但不能绑定到普通左值引用 (
T&
)。

当该对的第一个元素声明为

const
时,您无法将非常量右值引用 (
std::string&&
) 绑定到它。原因是它可以允许修改 const 对象,而这在 C++ 中是不允许的。因此,选择左值的重载,即
void func(const std::string& str)

这里重要的一点是

std::string&&
const std::string&
不是一回事。第一个是对临时字符串(可以修改)的引用,第二个是 const 左值引用,可以引用左值或右值,但不允许修改它所引用的对象。

当您从

const
中删除
MyPair
时,第一个参数变得可修改,因此,允许将其绑定到非常量右值引用 (
std::string&&
)。因此,在这种情况下,将调用
func
函数的右值版本。

总结一下,这里

const
的作用就是限制对象的修改。如果一个对象是
const
,则无法将非常量右值引用绑定到它,因为它将允许修改 const 对象。

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