const临时类型的最佳实践

bre*_*att 6 c++ c++14

假设我正在做一个涉及创建一个我不会修改的临时对象的计算:

auto tmp = val * val;
// Do some calculations with tmp...
Run Code Online (Sandbox Code Playgroud)

此外,我不需要tmp成为左值,因为我不会接受它的地址。

在这种情况下,我应该在代码中使用哪种惯用法:

1.       auto    tmp = val * val;
2. const auto    tmp = val * val;
3. const auto &  tmp = val * val;
4.       auto && tmp = val * val;
5. const auto && tmp = val * val;
Run Code Online (Sandbox Code Playgroud)

请注意,我明确地放弃了,auto &因为这通常会导致UB。但是,我知道const auto &可以延长temp的寿命,因此在此我将其保留为一种选择。

不出所料,对于这个简单的示例,-O3无论如何都会编译为相同的代码:https : //godbolt.org/z/oXj3hd

但是在一个更复杂的示例中,我想他们不会。

我的想法是,选项3或5可能是最正确的,因为它们将保留对象的恒定性,并且将保留临时对象。

编辑:

许多人提到了一个事实,在这个简单的示例中,甚至不需要命名临时文件。那是正确的。我所追求的是关于生成临时表达式的复杂操作的建议,并将在代码中重复使用。

for*_*818 6

为什么要绑定引用val * val?除了性能,我认为这是一种混淆。

毫不奇怪,对于这个简单的示例,-O3始终会编译为相同的代码:

是的,这里没有什么大的惊喜。因此,只需使用最简洁,最不人为。const不是为了性能,编译器足够聪明,可以意识到在没有您帮助的情况下就不会修改变量,尽管可以const为您记录常量,从而增加了可读性。因此

const auto tmp = val * val;
Run Code Online (Sandbox Code Playgroud)

其他任何事情都将简单的事情变成不必要的复杂事情。

最后但并非最不重要的一点是,考虑是否根本需要临时文件,或者是否可以简单地val*val代替编写tmp。另一方面,如果您使用了tmp很多次,那么给它起一个有意义的名称当然是值得的(有意义=比tmp;更有意义的东西)

附注:请注意,const不要偏离tmp,这可能会对性能造成不利影响。但是,通常,在担心性能时,应首先编写可读代码,然后再衡量性能。


lub*_*bgr 6

auto tmp = val * val;
Run Code Online (Sandbox Code Playgroud)

如果您想tmp稍后在(std::move(tmp))上强制转换为右值,请使用此选项。

const auto tmp = val * val;
Run Code Online (Sandbox Code Playgroud)

当您不需要std::move(tmp)以后使用此功能时。明确,毫不奇怪地授予Scott Meyers项目“ const尽可能使用”的荣誉。

const auto &  tmp = val * val;
Run Code Online (Sandbox Code Playgroud)

不要这样 它确实延长了生命周期,但是与2相比,您没有任何收获,因为对象无论如何都必须生活在某个地方。当val*val收益率的值的对象,你会不会跟2.复制因(N)静脉阻塞(假设operator *val三立对象的行为),所以const auto& tmpconst auto tmp都将引用一个对象的范围的堆内。

auto && tmp = val * val;
const auto && tmp = val * val;
Run Code Online (Sandbox Code Playgroud)

不会产生任何性能上的好处,但是会使代码的读取复杂化。不要这样