With C++ 17, we will have the possibility to return unmovable (including uncopyable) types such as std::mutex, via what can be thought of as guaranteed return v
templatestruct many { T1 a; T2 b; T3 c; }; auto f(){ return {string(),5.7, false} };
This won't compile. First you never said f is to return a many. Second, class template argument deduction work with constructors, and the only constructors of many are the implicitly declared default, copy and move constructors.
You need a guide:
template
many(T1, T2, T3) -> many;
auto get_ensured_rvo_str(){ return std::pair(std::string(),nocopy()); }
This doesn't work either. nocopy() is materialized into a temporary that is bound to the reference parameter of pair's constructor, which then attempts to move from it and fails. No elision of that temporary is possible or allowed.
(Of course, as Nicol Bolas points out in his answer, the class member access in get_ensured_rvo_str().first materializes the pair return value of get_ensured_rvo_str, so rvoStr would in fact be moved constructed from the first member of that materialized temporary. But here you have a problem well before that.)
auto get_class_and_mutex(){ return many{SomeClass(),std::mutex(),std::string()}; } auto [ mtx,sc,str ] = get_class_and_mutex();
This is fine (assuming you have a deduction guide). Aggregate initialization doesn't call any constructor of many; it initializes the members directly with the corresponding prvalue initializer.