A
Andrew Tomazos
class O {...};
class I {...};
class E {...};
Suppose we have some function f that takes an instance of class I as
input and produces an instance of class O as output (throwing an
instance of class E on an error):
O f(const I& i)
{
O result;
... // mutate result based on i
if (...)
throw E(...);
return result;
}
I i = ...;
O o = f(i);
In C++03 many times it was recommend to write such a function as
follows:
void f(O& out, const I& i)
{
.... // mutate result based on i
if (,,,)
throw E(...);
}
I i = ...;
O o;
f(o,i);
I suspect this is to avoid the (potentially expensive) copy
construction as the temporary O instance is copied from f's stack
frame to the callers.
The downside is that you then can't do things like:
f(i).callSomeOFunction()
or
someFunctionTakingAnO(f(i))
My question is with the advent of move constructors, xvalues and
rvalue references in C++11, is there anyway to address this issue?
What would this mean/do:
O&& f(const I& i)
{
O result;
... // mutate result based on i
if (...)
throw E(...);
return result; // or std::forward(result) ?
}
or is it broken?
Thanks,
Andrew.
class I {...};
class E {...};
Suppose we have some function f that takes an instance of class I as
input and produces an instance of class O as output (throwing an
instance of class E on an error):
O f(const I& i)
{
O result;
... // mutate result based on i
if (...)
throw E(...);
return result;
}
I i = ...;
O o = f(i);
In C++03 many times it was recommend to write such a function as
follows:
void f(O& out, const I& i)
{
.... // mutate result based on i
if (,,,)
throw E(...);
}
I i = ...;
O o;
f(o,i);
I suspect this is to avoid the (potentially expensive) copy
construction as the temporary O instance is copied from f's stack
frame to the callers.
The downside is that you then can't do things like:
f(i).callSomeOFunction()
or
someFunctionTakingAnO(f(i))
My question is with the advent of move constructors, xvalues and
rvalue references in C++11, is there anyway to address this issue?
What would this mean/do:
O&& f(const I& i)
{
O result;
... // mutate result based on i
if (...)
throw E(...);
return result; // or std::forward(result) ?
}
or is it broken?
Thanks,
Andrew.