使用最大优化设置编译和运行此代码似乎会产生相同的结果。
#include <stdio.h>
class A
{
public:
A() { }
const int* begin() const { return a; };
const int* end() const { printf("end\n"); return a + 3; };
bool isTrue() const { return true; }
int a[4];
};
const A a{};
class B
{
public:
const A& operator[](size_t) const { printf("B called\n"); return a; }
};
int main()
{
const B b{};
if (!b[0].isTrue()) return -1;
for (const auto& x : b[0]) printf("%d\n", x);
}我对B类型的常量对象调用b两次,operator[]返回A类型的常量对象。
为什么"B叫“被印了两次?为什么代码不能将b保存在一边,并在其上运行不同的功能?(由于这些函数是const函数,它们将返回相同的结果.)
发布于 2022-03-16 08:23:00
为什么"B叫“会被打印两次?
首先,因为您在main中引用了两次b[0]。而且因为操作符函数中的printf语句指示访问b[0]有副作用。所以编译器不能假设您的printf仅用于调试-它必须对每个调用调用一次。
如果我们删除printf语句并进行计算,就可以看到代码经过了很大的优化,可以在没有任何调用的情况下打印0三次。
发布于 2022-03-16 08:24:05
operator[]和其他函数一样是一个正常的函数,因为C++没有纯函数的概念,所以编译器必须假定每个函数都有副作用。一个这样的副作用是您的printf调用。如果您优化了对operator[]的一个调用,您的程序行为可能会改变(在这里,它只打印一次而不是两次)。想象一下,您将调用数据库或其他重要的东西而不是printf。如果只是经过优化,那就太糟糕了。
还请注意,const成员函数与纯函数并不相同。const意味着它不能修改调用成员函数的实例,但是仍然可以更改全局变量。您甚至无法保证const成员函数不会更改实例的状态,因为您可以在特定条件下丢弃const。
https://stackoverflow.com/questions/71493678
复制相似问题