UPDATE1: C++17 added type deduction for constructors - which does not imply that the free function is an inferior solution.
UPDATE2: C++17 added guaranteed copy elision (the copy does not even take place conceptually). So with C++17 my code actually works and with optimal performance. But Martinho's code using brace initialisation for the return value is still the cleaner solution I believe. But checkout this answer from Barry and the comment from T.C.
OLD POST: Type deduction does not work for constructors (at least until and including C++11). The common solution is to rely on RVO (Return Value Optimisation) and write a make_XYZ template function that forwards its parameters to the constructor. An example is std::make_tuple
.
Any template acrobat who knows a workaround to make this work when nocopy policy is in the way? A valid solution must still allow RVO to happen.
Additionally, will the requirement for any make_XYZ disappear with C++14?
#include <iostream>
template <typename T>
struct XYZ
{
// remove following two lines to make the code compile
XYZ (XYZ const & rhs) = delete;
XYZ (XYZ && rhs) = delete;
T i;
XYZ (T i):i(i)
{
}
};
template <typename T>
XYZ<T> make_XYZ (T && i)
{
return XYZ<T>(std::forward<T>(i));
}
int main ()
{
auto x = make_XYZ(1);
std::cout << x.i << std::endl;
}
auto const&
at the call site. – Creeconst
does not allow you to use refs to returned locals. – Rettarettigauto const &
solution is clearly very suboptimal and a constref does not even work for me. However, why should this answer not apply here? Seems I am still missing something (something that was clear to me when I knew less). – DiomedesT f(); T const& r = f();
it works becausef()
creates a temporary and it is bound tor
and lifetime extended. But forT const& f(); T const& r = f();
, it doesn't becausef()
gives a reference not a temporary to extend. – Wittman