在下面的例子中,vec
在调用std::reverse
之前和之后保持相同的顺序。如果我使Foo.a
不是const
,并删除复制赋值操作符,那么向量将正确地反转,但我不明白为什么。
在调试时,赋值操作符在std::reverse
内部调用时似乎确实正确地复制了对象,所以我不明白应该做些什么不同的事情。
#include <vector>
#include <algorithm>
#include <iostream>
struct Foo
{
Foo(int a, int b) : a(a), b(b) {}
Foo operator=(const Foo& other)
{
return Foo(other);
}
const int a;
int b;
Foo doThing()
{
Foo copy(*this);
copy.b++;
return copy;
}
};
void print(std::vector<Foo>& vec)
{
for (const auto& foo : vec)
{
std::cout << foo.b << '\n';
}
}
int main()
{
Foo initial(-1, 0);
std::vector<Foo> vec;
vec.push_back(initial);
for (size_t i = 0; i < 10; i++)
{
vec.push_back(vec[i].doThing());
}
std::cout << "before std::reverse \n\n";
print(vec);
std::reverse(vec.begin(), vec.end());
std::cout << "\nafter std::reverse \n\n";
print(vec);
std::cout.flush();
}
1条答案
按热度按时间q0qdq0h21#
这在c20之前是不可能的,因为
const
成员不能通过赋值w/o UB来改变,这也是为什么const
成员在对象中被强烈反对的原因。但是现在是了。但是你仍然需要写一个赋值运算符。为了将来证明代码(c23以上)你还应该包含一个copy ctor,因为隐式的copy ctor可能会被移除。下面是工作代码,不涉及UB: