Question
Enabling NRVO when forwarding a function's result via template function
When forwarding a function's result via template function, I encountered different behaviour regarding utilization of "named return value optimization (NRVO)" for clang and gcc. Here a code snippet:
Foo provideFooAsTemporary()
{
return Foo{};
}
template <typename TFn>
auto forwardA(TFn &&fn)
{
auto result = fn();
return result;
}
template <typename TFn>
auto forwardB(TFn &&fn) -> decltype(fn())
{
auto result = fn();
return result;
}
Foo fooA = forwardA(provideFooAsTemporary);
Foo fooB = forwardB(provideFooAsTemporary);
Here my observations (also see godbolt example):
gcc 14.1: Avoids any move operations for both
forwardA
andforwardB
.clang 18.0.1: Avoids moving only for
forwardB
, but a move operation occurs forforwardA
.
I would have expected that forwardA
triggers NRVO also for clang.
Here my questions:
What exactly is the difference between
forwardA
andforwardB
? Why does the specified trailing return type make a difference?Is there a simpler way to enable NRVO for clang than what is shown in
forwardB
?