模板表达式如何摆脱临时变量

Posted

技术标签:

【中文标题】模板表达式如何摆脱临时变量【英文标题】:How template expressions get rid of temporaries 【发布时间】:2016-07-10 09:04:55 【问题描述】:

我在阅读一些文章,其中许多提到表达式模板可以避免使用临时对象。但他们都没有提到这是如何完成的。据我所知,由于设计架构操作是使用临时对象完成的。例如,如果 a、b 和 c 是两个矩阵,如果我们这样做 a = b+c,那么 b+c 的结果将保存在一个临时对象中,例如 temp = b+c,然后将结果复制回类似 a = temp 的对象中。

但是如果我们使用表达式模板,那么这个加法(+)操作会返回 b 和 c 的引用,然后主要计算发生在赋值运算符(=)被评估时。这是模板表达式的简单通用概念。但我不明白它是如何摆脱临时对象的。如果有人能给出如何避免这种临时性的一般想法,那就太好了。

【问题讨论】:

您可能会发现this answer 是一个相关但不重复的问题,很有趣。 你仍然得到一个临时对象,但不是最终类型,你有一个临时包装器。 【参考方案1】:

为例
Vector a,b,c,d;
a = b + c + d;

通常这会转化为类似

a = b.operator+( c.operator+(d) );

operator+ 的每次调用都必须遍历条目。但是,更自然的方法是遍历所有元素一次并进行一些添加,例如

a_i = b_i + c_i + d_i

这就是表达式模板通过仅在真正需要结果时才评估表达式来有效执行的操作。

请注意,仅需要临时(即c+d 的中间结果),因为每个operator+ 单独循环遍历所有元素。一旦单独的循环组合在一起,就不再需要临时的了。

对于一个不那么业余的解释和更多细节,我可以向你推荐这个talk from the CppConf 2015。

【讨论】:

以上是关于模板表达式如何摆脱临时变量的主要内容,如果未能解决你的问题,请参考以下文章

sql server中的临时表表变量和公用表表达式

重构手法之Replace Temp with Query(以查询取代临时变量)

设置临时变量并在pug模板中进一步重用它

代码重构之内联临时变量

1.3 将临时变量内联化

重构改善既有代码设计--重构手法04:Replace Temp with Query (以查询取代临时变量)