标准做法是在C++中使用表达式模板来提高效率,通过消除不必要的临时对象。为什么C++编译器不能自动删除这些不必要的临时对象呢?
这个问题我认为已经知道答案,但由于无法在网上找到低级别的回答,因此希望确认一下。
表达式模板基本上允许/强制进行极端程度的内联。然而,即使进行内联,编译器也无法通过优化调用operator new和operator delete来删除这些多余的临时对象,因为它们将这些调用视为不透明的,因为这些调用可以在其他翻译单元中被重写。表达式模板完全删除了这些中间对象的调用。
可以在一个简单的例子中看到这些多余的operator new和operator delete的调用,例如我们只复制:
在生成的代码中,我们可以看到
这个分析正确吗?
在C++中,是否有可能合法地省略
这个问题我认为已经知道答案,但由于无法在网上找到低级别的回答,因此希望确认一下。
表达式模板基本上允许/强制进行极端程度的内联。然而,即使进行内联,编译器也无法通过优化调用operator new和operator delete来删除这些多余的临时对象,因为它们将这些调用视为不透明的,因为这些调用可以在其他翻译单元中被重写。表达式模板完全删除了这些中间对象的调用。
可以在一个简单的例子中看到这些多余的operator new和operator delete的调用,例如我们只复制:
#include <array>
#include <vector>
std::vector<int> foo(std::vector<int> x)
{
std::vector<int> y{x};
std::vector<int> z{y};
return z;
}
std::array<int, 3> bar(std::array<int, 3> x)
{
std::array<int, 3> y{x};
std::array<int, 3> z{y};
return z;
}
在生成的代码中,我们可以看到
foo()
编译成了一个相对较长的函数,其中调用了两个operator new
和一个operator delete
,而bar()
只编译成了寄存器的传递,并且没有进行任何不必要的拷贝。这个分析正确吗?
在C++中,是否有可能合法地省略
foo()
中的复制操作?
Matrix a, b, c, d = ....;
Matrix r = a + b * c + d
; 表达式模板在表达式a + b * c + d
中发挥作用,这种技术所做的是,它不会立即计算b*c
,然后计算a + temp1
,再计算temp2 + d
,而是将算术计算延迟到赋值时。它通过使用模板创建一个在编译时已知的 AST 对象来实现这一点,用于表达式a + b * c + d
。 - bolov