使用 std::optional 时命名为 Return 值优化
Named Return Value Optimization when using std::optional
我最近发现 std::optional
可以提高代码的清晰度,尤其是 return 函数值。但是我对它对性能的影响有疑问。更具体地说,我想知道是否可以编写类似于下面的代码,允许编译器应用命名 Return 值优化。
struct Data
{
int x;
int y;
};
std::optional<Data> makeData(bool condition)
{
Data data;
if(condition)
{
data.x = 2.0;
data.y = 2.0;
return data;
}
else
{
return {};
}
}
嗯,在这种情况下,as-if 规则已经足够了:Data
是平凡可复制和平凡可破坏的,所以你无法观察编译器是否复制它,或者它是否直接将它构造到std::optional<Data>
return 对象。不需要 NRVO 来防止复制。
假设您给了 Data
一个带有副作用的复制构造函数。那么 NRVO 是否适用的问题将是相关的。答案是否定的:NRVO 不适用,因为局部变量的类型不同于函数 return 类型。为了让 NRVO 发生,你可以这样写:
std::optional<Data> r;
if (condition) {
r.emplace();
r.x = 2.0;
r.y = 2.0;
}
return r;
我最近发现 std::optional
可以提高代码的清晰度,尤其是 return 函数值。但是我对它对性能的影响有疑问。更具体地说,我想知道是否可以编写类似于下面的代码,允许编译器应用命名 Return 值优化。
struct Data
{
int x;
int y;
};
std::optional<Data> makeData(bool condition)
{
Data data;
if(condition)
{
data.x = 2.0;
data.y = 2.0;
return data;
}
else
{
return {};
}
}
嗯,在这种情况下,as-if 规则已经足够了:Data
是平凡可复制和平凡可破坏的,所以你无法观察编译器是否复制它,或者它是否直接将它构造到std::optional<Data>
return 对象。不需要 NRVO 来防止复制。
假设您给了 Data
一个带有副作用的复制构造函数。那么 NRVO 是否适用的问题将是相关的。答案是否定的:NRVO 不适用,因为局部变量的类型不同于函数 return 类型。为了让 NRVO 发生,你可以这样写:
std::optional<Data> r;
if (condition) {
r.emplace();
r.x = 2.0;
r.y = 2.0;
}
return r;