按值返回和按常量引用传递时避免临时构造
Avoiding temporary construction when returning by value and passing by const reference
我有一个函数可以通过 const 引用接受 Large
:
void func(const Large& param);
和一个 class 持有 Large
:
class HoldsLarge {
public:
Large GetByValue() const { return l; };
private:
Large l;
}
如果我这样做
HoldsLarge x;
func(x.GetByValue());
我的理解是否正确,临时文件将是为 x.GetByValue()
构造的副本,它将通过引用传递给 func
?标准中是否有允许编译器完全省略临时构造的内容?毕竟,func
只需要 const
引用 HoldsLarge::l
.
我知道我可以简单地 return HoldsLarge::l
通过 const 引用,但我想防止客户意外创建悬空引用。
在少数情况下允许编译器更改行为(作为优化):对于 NRVO,以及从 C++14 开始的新表达式。
你不属于那种情况。
那么;只要可观察到的行为相同,as-if 规则就允许进行任何优化。
因此,只有在 不改变行为的情况下,编译器才能进行优化。
在不知道 func
的情况下,它无法安全地这样做。
func
可能可以从另一种方式(作为全局)访问 x.l
(或别名)。
例如,跟随 func
将禁止更改。
Large* largePtr; // possibly set to &x.l by any way
void func(const Large& param)
{
print(param.x);
//param might be alias of largePtr
mutate(alias->x);
print(param.x); // const ref should see the modification
// whereas copy don't
}
我有一个函数可以通过 const 引用接受 Large
:
void func(const Large& param);
和一个 class 持有 Large
:
class HoldsLarge {
public:
Large GetByValue() const { return l; };
private:
Large l;
}
如果我这样做
HoldsLarge x;
func(x.GetByValue());
我的理解是否正确,临时文件将是为 x.GetByValue()
构造的副本,它将通过引用传递给 func
?标准中是否有允许编译器完全省略临时构造的内容?毕竟,func
只需要 const
引用 HoldsLarge::l
.
我知道我可以简单地 return HoldsLarge::l
通过 const 引用,但我想防止客户意外创建悬空引用。
在少数情况下允许编译器更改行为(作为优化):对于 NRVO,以及从 C++14 开始的新表达式。
你不属于那种情况。
那么;只要可观察到的行为相同,as-if 规则就允许进行任何优化。
因此,只有在 不改变行为的情况下,编译器才能进行优化。
在不知道 func
的情况下,它无法安全地这样做。
func
可能可以从另一种方式(作为全局)访问 x.l
(或别名)。
例如,跟随 func
将禁止更改。
Large* largePtr; // possibly set to &x.l by any way
void func(const Large& param)
{
print(param.x);
//param might be alias of largePtr
mutate(alias->x);
print(param.x); // const ref should see the modification
// whereas copy don't
}