我对左值和右值有一些了解。因此,据我所知,我们不能分配给右值,但是非常量左值是可以的。
#include <iostream>
#include <vector>
int main(){
std::vector<int> v{ 1, 2, 3, 4, 5 };
v.begin() = v.end() - 2;
std::cout << *v.begin() << std::endl; // 1
for (auto const& e : v)
std::cout << e << ", ";// 1, 2, 3, 4, 5,
std::cout << std::endl;
}
为什么我可以分配给begin()
却对元素没有任何作用?
答案 0 :(得分:17)
v.begin()
是一个迭代器。分配给迭代器不会分配给迭代器指向的值。此外,由于v.begin()
是一个prvalue,因此分配给您的对象在行的末尾被销毁,而不会影响v
或它拥有的任何“永久”内存。
如果v.begin()
是原始指针,则编译器将在尝试分配给右值时发出错误。但是,类型std::vector<T>::iterator
通常是类类型,在您的实现中似乎是这种情况(带有正在使用的特定编译器标志集),因此分配给v.begin()
会调用{该类类型的{1}}。但这并不能改变以下事实:迭代器对象是一个临时对象,对其进行分配不会产生进一步的影响。
为了分配给operator=
所指向的元素,您需要取消引用:v.begin()
答案 1 :(得分:6)
分配给std :: vector :: begin()的结果是什么?
赋值表达式的结果(在您的示例中结果被舍弃)是赋值。在这种情况下,结果与v.end() - 2
相同。
请注意,由于begin()
返回一个值,因此此分配仅修改返回的临时对象。分配不会以任何方式修改向量。考虑到临时对象被丢弃,该分配在实践中没有可观察到的效果。
此外,如果标准库选择将std::vector::iterator
实现为指针,则此赋值可能格式错误。
为什么我可以分配给
begin()
因为
但是它对元素没有任何作用吗?
因为分配迭代器不会修改迭代器指向的元素。相反,分配会更改迭代器指向的对象。
据我所知,我们无法分配给右值
这通常是不正确的。尤其是对于类类型†而言并非如此。
†除非该类的赋值运算符具有lvalue-ref-qualifier(并且没有rvalue-ref限定的重载),否则这是非常规的。
答案 2 :(得分:3)
有时代码比单词更能说明问题。您的代码与此等效:
std::vector<int> v{ 1, 2, 3, 4, 5 };
{
auto temp = v.begin();
temp = v.end() - 2;
}
std::cout << *v.begin() << std::endl; // 1
for (auto const& e : v)
std::cout << e << ", ";// 1, 2, 3, 4, 5,
std::cout << std::endl;
换句话说,v.begin() = v.end() - 2
没有明显的作用。这只是对临时工的分配。