In this example, a foo instance does nothing but print whether it's copy- or move-constructed.
#include <iostream>
#include <algorithm>
#include <vector>
struct foo {
foo()=default;
foo(foo &&) { std::cout << "move constructed\n"; }
foo(const foo &) { std::cout << "copy constructed\n"; }
};
int main()
{
foo x;
std::vector<int> v; // empty
std::remove_if(v.begin(), v.end(),
[x=std::move(x)](int i){ return false; });
}
This produces the following output:
move constructed
copy constructed
move constructed
move constructed
copy constructed
copy constructed
Questions:
Why does std::remove_if create so many closures ?
Even if multiple intermediate instances are necessary, one would expect they are all rvalues; so why are some of them copy-constructed ?
Compiler is gcc 8.1.1
If we take a look at the implementation of std::remove_if in gcc's libstdc++-v3 we notice that the predicate is passed down the call chain (by value, at times) a few steps before reaching the lowermost __find_if function (used by remove_if).
Let's count the moves and copies:
move constructed when the predicate (including the captured x) is sent by value, but as a non-lvalue, to std::remove_if entry point
copy constructed when passed on to the __gnu_cxx::__ops::__pred_iter(...) function, which in turn:
invokes the _GLIBCXX_MOVE macro, thus the move constructed,
which moves the predicate over to the _Iter_pred ctor which moves it (move constructed) into the _M_pred member.
The call from std::remove_if to std::__remove_if seems to be optimized, as the _Iter_pred is not an lvalue, I guess, but __remove_if in turn pass on the wrapped predicate, by value, to std::__find_if, for another copy constructed invocation.
std::__find_if, in turn, forwards the wrapped predicate, by value, to another __find_if overload, which is finally the sink of this call chain, and the final copy constructed.
It can be interesting to compare with e.g. clang's implementation of std::remove_if, as clang (6.0.1) do not produce this move-copy chain for OP's std::remove_if example. A quick glance shows that It seems as if clang use traits on the predicates type to make sure to pass the predicate as an lvalue reference.
Both clang and gcc produce the same move/copy chains for the contrived example that follows, which shows a similar chain to gcc's implementation:
#include <iostream>
#include <utility>
struct foo {
foo() = default;
foo(foo &&) { std::cout << "move constructed\n"; }
foo(const foo &) { std::cout << "copy constructed\n"; }
};
template <typename Pred>
struct IterPred {
Pred m_pred;
explicit IterPred(Pred pred) : m_pred(std::move(pred)) {}
};
template <typename T>
inline IterPred<T> wrap_in_iterpred (T l) {
return IterPred<T>(std::move(l));
}
template <typename T>
void find_if_overload(T l) {
(void)l;
}
template <typename T>
void find_if_entrypoint(T l) {
find_if_overload(l);
}
template <typename T>
void remove_if_entrypoint(T l) {
find_if_entrypoint(
wrap_in_iterpred(l));
}
int main()
{
foo x;
remove_if_entrypoint([x=std::move(x)](int){ return false; });
}
Where both gcc (8.2.0) and clang (6.0.1) produces the following chain:
move constructed
copy constructed
move constructed
move constructed
copy constructed
Related
In the following code, it seems that the compiler sometimes prefer to call the templated constructor and fails to compile when a copy constructor should be just fine. The behavior seems to change depending on whether the value is captured as [v] or [v = v], I thought those should be exactly the same thing. What am I missing?
I'm using gcc 11.2.0 and compiling it with "g++ file.cpp -std=C++17"
#include <functional>
#include <iostream>
#include <string>
using namespace std;
template <class T>
struct record {
explicit record(const T& v) : value(v) {}
record(const record& other) = default;
record(record&& other) = default;
template <class U>
record(U&& v) : value(forward<U>(v)) {} // Removing out this constructor fixes print1
string value;
};
void call(const std::function<void()>& func) { func(); }
void print1(const record<string>& v) {
call([v]() { cout << v.value << endl; }); // This does not compile, why?
}
void print2(const record<string>& v) {
call([v = v]() { cout << v.value << endl; }); // this compiles fine
}
int main() {
record<string> v("yo");
print1(v);
return 0;
}
I don't disagree with 康桓瑋's answer, but I found it a little hard to follow, so let me explain it with a different example. Consider the following program:
#include <functional>
#include <iostream>
#include <typeinfo>
#include <type_traits>
struct tracer {
tracer() { std::cout << "default constructed\n"; }
tracer(const tracer &) { std::cout << "copy constructed\n"; }
tracer(tracer &&) { std::cout << "move constructed\n"; }
template<typename T> tracer(T &&t) {
if constexpr (std::is_same_v<T, const tracer>)
std::cout << "template constructed (const rvalue)\n";
else if constexpr (std::is_same_v<T, tracer&>)
std::cout << "template constructed (lvalue)\n";
else
std::cout << "template constructed (other ["
<< typeid(T).name() << "])\n";
}
};
int
main()
{
using fn_t = std::function<void()>;
const tracer t;
std::cout << "==== value capture ====\n";
fn_t([t]() {});
std::cout << "==== init capture ====\n";
fn_t([t = t]() {});
}
When run, this program outputs the following:
default constructed
==== value capture ====
copy constructed
template constructed (const rvalue)
==== init capture ====
copy constructed
move constructed
So what's going on here? First, note in both cases, the compiler must materialize a temporary lambda object to pass into the constructor for fn_t. Then, the constructor of fn_t must make a copy of the lambda object to hold on to it. (Since in general the std::function may outlive the lambda that was passed in to its constructor, it cannot retain the lambda by reference only.)
In the first case (value capture), the type of the captured t is exactly the type of t, namely const tracer. So you can think of the unnamed type of the lambda object as some kind of compiler-defined struct that contains a field of type const tracer. Let's give this structure a fake name of LAMBDA_T. So the argument to the constructor to fn_t is of type LAMBDA_T&&, and an expression that accesses the field inside is consequently of type const tracer&&, which matches the template constructor's forwarding reference better than the actual copy constructor. (In overload resolution rvalues prefer binding to rvalue references over binding to const lvalue references when both are available.)
In the second case (init capture), the type of the captured t = t is equivalent to the type of tnew in a declaration like auto tnew = t, namely tracer. So now the field in our internal LAMBDA_T structure is going to be of type tracer rather than const tracer, and when an argument of type LAMBDA_T&& to fn_t's constructor must be move-copied, the compiler will choose tracer's normal move constructor for moving that field.
For [v], the type of the lambda internal member variable v is const record, so when you
void call(const std::function<void()>&);
void print1(const record<string>& v) {
call([v] { });
}
Since [v] {} is a prvalue, when it initializes const std::function&, v will be copied with const record&&, and the template constructor will be chosen because it is not constrained.
In order to invoke v's copy constructor, you can do
void call(const std::function<void()>&);
void print1(const record<string>& v) {
auto l = [v] { };
call(l);
}
For [v=v], the type of the member variable v inside the lambda is record, so when the prvalue lambda initializes std::function, it will directly invoke the record's move constructor since record&& better matches.
Lets say you have a variadic class with a std::tuple, that can be move constructed with args + 1 new arg. When constructed using std::apply() and a raw curly brace constructor, that constructor doesn't return an rvalue. Which means the class isn't move constructed. An example follows to clarify.
#include <cstdio>
#include <tuple>
#include <type_traits>
#include <unordered_map>
#include <vector>
template <class... Args>
struct icecream {
icecream() = default;
template <class... MoreArgs>
icecream(icecream<MoreArgs...>&& ice) {
std::apply(
[this](auto&&... ds) {
data = { std::move(ds)..., {} };
},
std::move(ice.data));
}
// This works :
// template <class... MoreArgs>
// icecream(icecream<MoreArgs...>&& ice) {
// std::apply(
// [this](auto&&... ds) {
// data = { std::move(ds)...,
// std::move(std::vector<double>{}) };
// },
// std::move(ice.data));
// }
std::tuple<std::vector<Args>...> data{};
};
int main(int, char**) {
icecream<int> miam;
std::get<0>(miam.data).push_back(1);
std::get<0>(miam.data).push_back(2);
icecream<int, double> cherry_garcia{ std::move(miam) };
printf("miam : \n");
for (const auto& x : std::get<0>(miam.data)) {
printf("%d\n", x);
}
printf("\ncherry_garcia : \n");
for (const auto& x : std::get<0>(cherry_garcia.data)) {
printf("%d\n", x);
}
return 0;
}
The output is :
miam :
1
2
cherry_garcia :
1
2
The example is a little dumbed down, but illustrates the point. In the first move constructor, {} is used and the tuple copy constructs. If you uncomment the second constructor with a hardcoded std::move(), then it works.
I test on VS latest, clang latest and gcc latest. All have the same result. (wandbox : https://wandbox.org/permlink/IQqqlLcmeyOzsJHC )
So the question is, why not return an rvalue? I'm obviously missing something with the curly constructor. This might have nothing to do with the variadic stuff, but I thought I might as well show the real scenario.
Why doesn't raw curly constructor {} return an rvalue?
The problem is another.
The problem is that
data = { std::move(ds)..., {} };
call the "direct constructor" (constructor (2) in this page),
constexpr tuple( const Types&... args ); (2)
not the "converting constructor" (constructor (3))
template< class... UTypes >
constexpr tuple( UTypes&&... args ); (3)
that you expect.
The problem is that "{}" isn't enough, for the compiler, to deduce a type (the last type for UTypes... list in constructor (3)) so the constructor (3) is excluded and the compiler choose the constructor (2).
Whit constructor (2), "{}" is acceptable to construct an object of the last type of the Types... of the list because the Types... is know and not to be deduced.
But constructor (2) is a copy constructor (from the point of view of the Types... of the tuple), not a forward constructor as constructor (3), so the first vector is copied, not moved.
It's different when you call
data = { std::move(ds)..., std::move(std::vector<double>{}) };
or also
data = { std::move(ds)..., std::vector<double>{} };
because the last argument can be clearly deduced as std::vector<double>{} && so the compiler call the "converting constructor" (constructor (3)) and move the content of the first vector.
Off Topic: instead of using std::vector<double>{}, that works only when double is the last of the types in Args..., I suggest to write a more generic code using std::tuple_element.
Moreover, I suggest to SFINAE enable your constructor only when sizeof...(MoreArgs)+1u == sizeof...(Args).
Maybe also std::forward() (enabling perfect forwarding) instead of std::move() inside the lambda.
So I suggest the following constructor
template <typename ... MoreArgs,
std::enable_if_t<sizeof...(MoreArgs)+1u == sizeof...(Args)> * = nullptr>
icecream(icecream<MoreArgs...>&& ice) {
std::apply(
[this](auto && ... ds) {
data = { std::forward<decltype(ds)>(ds)...,
std::tuple_element_t<sizeof...(Args)-1u,
decltype(data)>{} };
},
std::move(ice.data));
}
I am trying avoid output arguments in my functions. The old function is:
void getAllBlockMeanError(
const vector<int> &vec, vector<int> &fact, vector<int> &mean, vector<int> &err)
Here vec is input argument, fact, mean and err are output argument. I tried to group output argument to one tuple:
tuple< vector<int>, vector<int>, vector<int> >
getAllBlockMeanErrorTuple(const vector<int> &vec)
{
vector<int> fact, mean, err;
//....
return make_tuple(fact, mean, err);
}
Now I can call the new function with:
tie(fact, mean, err) = getAllBlockMeanErrorTuple(vec);
It looks cleaner to me. While I have a question, how does equal assignment of tie(fact, mean, err) work? Does it do a deep copy or a move? Since fact, mean and err inside getAllBlockMeanErrorTuple will be destroyed, I hope it is doing a move instead of a deep copy.
You function signature is tuple< vector<int>, vector<int>, vector<int> >, which is a temporary and the elements are eligible to be moved, so
std::tie(fact, mean, err) = getAllBlockMeanErrorTuple(vec)
should move-assign fact, mean, and err.
Here's a sample program for you to see for yourself (demo):
#include <iostream>
#include <vector>
#include <tuple>
struct A
{
A() = default;
~A() = default;
A(const A&)
{
std::cout << "Copy ctor\n";
}
A(A&&)
{
std::cout << "Move ctor\n";
}
A& operator=(const A&)
{
std::cout << "Copy assign\n";
return *this;
}
A& operator=(A&&)
{
std::cout << "Move assign\n";
return *this;
}
};
std::tuple<A, A> DoTheThing()
{
A first;
A second;
return std::make_tuple(first, second);
}
int main()
{
A first;
A second;
std::tie(first, second) = DoTheThing();
}
Output:
Copy ctor
Copy ctor
Move assign
Move assign
Note that the function had to create copies of the vectors for returning the tuple, which may not be what you want. You may want to std::move the elements into std::make_tuple:
return make_tuple(std::move(fact), std::move(mean), std::move(err));
Here's the same example as above, but with std::move used in make_tuple
Note that with C++17's Structured Bindings, you can forget about using std::tie at all, and lean more on auto (Thanks, #Yakk):
auto[fact, mean, err] = getAllBlockMeanErrorTuple(vec);
The early implementations of the C++17 standard for clang (3.8.0) and gcc (6.1.0) don't support it yet, however it seems there is some support in clang 4.0.0: Demo (Thanks, #Revolver_Ocelot)
You'll notice that the output with structured bindings changes to:
Move ctor
Move ctor
Indicating that they take advantage of copy-elision, which saves additional move operations.
std::tie(fact, mean, err) = getAllBlockMeanErrorTuple(vec);
would do a move assignment.
But as mentioned in comment
return make_tuple(fact, mean, err);
would do a copy, you may solve that with:
return make_tuple(std::move(fact), std::move(mean), std::move(err));
Imagine you have a number of overloaded methods that (before C++11) looked like this:
class MyClass {
public:
void f(const MyBigType& a, int id);
void f(const MyBigType& a, string name);
void f(const MyBigType& a, int b, int c, int d);
// ...
};
This function makes a copy of a (MyBigType), so I want to add an optimization by providing a version of f that moves a instead of copying it.
My problem is that now the number of f overloads will duplicate:
class MyClass {
public:
void f(const MyBigType& a, int id);
void f(const MyBigType& a, string name);
void f(const MyBigType& a, int b, int c, int d);
// ...
void f(MyBigType&& a, int id);
void f(MyBigType&& a, string name);
void f(MyBigType&& a, int b, int c, int d);
// ...
};
If I had more parameters that could be moved, it would be unpractical to provide all the overloads.
Has anyone dealt with this issue? Is there a good solution/pattern to solve this problem?
Thanks!
Herb Sutter talks about something similar in a cppcon talk
This can be done but probably shouldn't. You can get the effect out using universal references and templates, but you want to constrain the type to MyBigType and things that are implicitly convertible to MyBigType. With some tmp tricks, you can do this:
class MyClass {
public:
template <typename T>
typename std::enable_if<std::is_convertible<T, MyBigType>::value, void>::type
f(T&& a, int id);
};
The only template parameter will match against the actual type of the parameter, the enable_if return type disallows incompatible types. I'll take it apart piece by piece
std::is_convertible<T, MyBigType>::value
This compile time expression will evaluate to true if T can be converted implicitly to a MyBigType. For example, if MyBigType were a std::string and T were a char* the expression would be true, but if T were an int it would be false.
typename std::enable_if<..., void>::type // where the ... is the above
this expression will result in void in the case that the is_convertible expression is true. When it's false, the expression will be malformed, so the template will be thrown out.
Inside the body of the function you'll need to use perfect forwarding, if you are planning on copy assigning or move assigning, the body would be something like
{
this->a_ = std::forward<T>(a);
}
Here's a coliru live example with a using MyBigType = std::string. As Herb says, this function can't be virtual and must be implemented in the header. The error messages you get from calling with a wrong type will be pretty rough compared to the non-templated overloads.
Thanks to Barry's comment for this suggestion, to reduce repetition, it's probably a good idea to create a template alias for the SFINAE mechanism. If you declare in your class
template <typename T>
using EnableIfIsMyBigType = typename std::enable_if<std::is_convertible<T, MyBigType>::value, void>::type;
then you could reduce the declarations to
template <typename T>
EnableIfIsMyBigType<T>
f(T&& a, int id);
However, this assumes all of your overloads have a void return type. If the return type differs you could use a two-argument alias instead
template <typename T, typename R>
using EnableIfIsMyBigType = typename std::enable_if<std::is_convertible<T, MyBigType>::value,R>::type;
Then declare with the return type specified
template <typename T>
EnableIfIsMyBigType<T, void> // void is the return type
f(T&& a, int id);
The slightly slower option is to take the argument by value. If you do
class MyClass {
public:
void f(MyBigType a, int id) {
this->a_ = std::move(a); // move assignment
}
};
In the case where f is passed an lvalue, it will copy construct a from its argument, then move assign it into this->a_. In the case that f is passed an rvalue, it will move construct a from the argument and then move assign. A live example of this behavior is here. Note that I use -fno-elide-constructors, without that flag, the rvalue cases elides the move construction and only the move assignment takes place.
If the object is expensive to move (std::array for example) this approach will be noticeably slower than the super-optimized first version. Also, consider watching this part of Herb's talk that Chris Drew links to in the comments to understand when it could be slower than using references. If you have a copy of Effective Modern C++ by Scott Meyers, he discusses the ups and downs in item 41.
You may do something like the following.
class MyClass {
public:
void f(MyBigType a, int id) { this->a = std::move(a); /*...*/ }
void f(MyBigType a, string name);
void f(MyBigType a, int b, int c, int d);
// ...
};
You just have an extra move (which may be optimized).
My first thought is that you should change the parameters to pass by value. This covers the existing need to copy, except the copy happens at the call point rather than explicitly in the function. It also allows the parameters to be created by move construction in a move-able context (either unnamed temporaries or by using std::move).
Why you would do that
These extra overloads only make sense, if modifying the function paramers in the implementation of the function really gives you a signigicant performance gain (or some kind of guarantee). This is hardly ever the case except for the case of constructors or assignment operators. Therefore, I would advise you to rethink, whether putting these overloads there is really necessary.
If the implementations are almost identical...
From my experience this modification is simply passing the parameter to another function wrapped in std::move() and the rest of the function is identical to the const & version. In that case you might turn your function into a template of this kind:
template <typename T> void f(T && a, int id);
Then in the function implementation you just replace the std::move(a) operation with std::forward<T>(a) and it should work. You can constrain the parameter type T with std::enable_if, if you like.
In the const ref case: Don't create a temporary, just to to modify it
If in the case of constant references you create a copy of your parameter and then continue the same way the move version works, then you may as well just pass the parameter by value and use the same implementation you used for the move version.
void f( MyBigData a, int id );
This will usually give you the same performance in both cases and you only need one overload and implementation. Lots of plusses!
Significantly different implementations
In case the two implementations differ significantly, there is no generic solution as far as I know. And I believe there can be none. This is also the only case, where doing this really makes sense, if profiling the performance shows you adequate improvements.
You might introduce a mutable object:
#include <memory>
#include <type_traits>
// Mutable
// =======
template <typename T>
class Mutable
{
public:
Mutable(const T& value) : m_ptr(new(m_storage) T(value)) {}
Mutable(T& value) : m_ptr(&value) {}
Mutable(T&& value) : m_ptr(new(m_storage) T(std::move(value))) {}
~Mutable() {
auto storage = reinterpret_cast<T*>(m_storage);
if(m_ptr == storage)
m_ptr->~T();
}
Mutable(const Mutable&) = delete;
Mutable& operator = (const Mutable&) = delete;
const T* operator -> () const { return m_ptr; }
T* operator -> () { return m_ptr; }
const T& operator * () const { return *m_ptr; }
T& operator * () { return *m_ptr; }
private:
T* m_ptr;
char m_storage[sizeof(T)];
};
// Usage
// =====
#include <iostream>
struct X
{
int value = 0;
X() { std::cout << "default\n"; }
X(const X&) { std::cout << "copy\n"; }
X(X&&) { std::cout << "move\n"; }
X& operator = (const X&) { std::cout << "assign copy\n"; return *this; }
X& operator = (X&&) { std::cout << "assign move\n"; return *this; }
~X() { std::cout << "destruct " << value << "\n"; }
};
X make_x() { return X(); }
void fn(Mutable<X>&& x) {
x->value = 1;
}
int main()
{
const X x0;
std::cout << "0:\n";
fn(x0);
std::cout << "1:\n";
X x1;
fn(x1);
std::cout << "2:\n";
fn(make_x());
std::cout << "End\n";
}
This is the critical part of the question:
This function makes a copy of a (MyBigType),
Unfortunately, it is a little ambiguous. We would like to know what is the ultimate target of the data in the parameter. Is it:
1) to be assigned to an object that existing before f was called?
2) or instead, stored in a local variable:
i.e:
void f(??? a, int id) {
this->x = ??? a ???;
...
}
or
void f(??? a, int id) {
MyBigType a_copy = ??? a ???;
...
}
Sometimes, the first version (the assignment) can be done without any copies or moves. If this->x is already long string, and if a is short, then it can efficiently reuse the existing capacity. No copy-construction, and no moves. In short, sometimes assignment can be faster because we can skip the copy contruction.
Anyway, here goes:
template<typename T>
void f(T&& a, int id) {
this->x = std::forward<T>(a); // is assigning
MyBigType local = std::forward<T>(a); // if move/copy constructing
}
If the move version will provide any optimization then the implementation of the move overloaded function and the copy one must be really different. I don't see a way to get around this without providing implementations for both.
I'm trying to implement a class, say Foo, which follows RAII, and objects of the class are returned to the client by value, i.e.
class SomeClass {
public:
class Foo {
public:
~Foo() { /* follow raii */ }
private:
friend class SomeClass;
Foo() { /* follow raii */ }
};
Foo getFoo() { return Foo(); }
};
My immediate question would be is there any way to be sure that only one object of type Foo is constructed when calling SomeClass::getFoo()? I would think that most compilers know only one object need be constructed, but I know this is not guaranteed in most cases. Is there a better approach I can take?
I've tried returning a boost::shared_ptr<Foo> and just allocating a Foo object when constructing the shared pointer, and this works nicely. However, it does not seem ideal, as it requires heap allocation and makes for a less-clean interface.
Thanks!
Clarification
Visual Studio 2005 compiler so I don't think R-val references and C++11 related features are available.
You've taken the best approach. The copy (or in fact move in C++11) will almost surely be elided by the compiler. In fact, even the copy from the return value to some object in the calling code will probably be elided too. So this will only call a single constructor:
Foo foo = sc.getFoo();
The rule that allows both of these copies (or moves) to be elided is:
when a temporary class object that has not been bound to a reference (12.2) would be copied/moved to a class object with the same cv-unqualified type, the copy/move operation can be omitted by constructing the temporary object directly into the target of the omitted copy/move
boost::optional + boost::in_place
If copy constructor is dangerous, it is better to disable it completely.
Though most of compilers would elide copies in your case, some times it is possible to disable copy elision, for instance -fno-elide-constructors - and if code which "believes" in copy-elision would happen to run on such settings - there may be fireworks.
In C++98 you may use boost::optional + boost::in_place - there is no heap allocation, becuase boost::optional reserves enough place. And it is guaranteed that there will be no any copies.
live demo
#include <boost/utility/in_place_factory.hpp>
#include <boost/noncopyable.hpp>
#include <boost/optional.hpp>
#include <iostream>
#include <ostream>
using namespace boost;
using namespace std;
struct Foo: private noncopyable
{
explicit Foo(int i)
{
cout << "construction i=" << i << endl;
}
};
void make(optional<Foo> &foo)
{
foo = in_place(11);
}
int main()
{
optional<Foo> foo;
cout << "*" << endl;
make(foo);
cout << "!" << endl;
}
Output is:
*
construction i=11
!
This code does work on MSVC2005.
Boost.Move
Another option is to use move semantic emulation for C++98 - Boost.Move. Copies are disabled:
live demo
#include <boost/move/utility.hpp>
#include <iostream>
#include <ostream>
using namespace std;
class Movable
{
BOOST_MOVABLE_BUT_NOT_COPYABLE(Movable)
bool own_resource;
public:
Movable()
: own_resource(true)
{}
~Movable()
{
cout << (own_resource ? "owner" : "empty") << endl;
}
Movable(BOOST_RV_REF(Movable) x)
: own_resource(x.own_resource)
{
x.own_resource = false;
}
Movable& operator=(BOOST_RV_REF(Movable) x)
{
own_resource = x.own_resource;
x.own_resource = false;
return *this;
}
};
Movable make()
{
return Movable();
}
int main()
{
Movable m = make();
}
Output is:
empty
empty
owner
This code also does work on MSVC2005.
C++11
In C++11 use following approach:
live demo
struct Foo
{
Foo(const Foo &)=delete;
Foo(Foo &&)=delete;
Foo &operator=(const Foo&)=delete;
Foo &operator=(Foo &&)=delete;
Foo(int){}
};
Foo create()
{
//return Foo{0}; // ERROR: needs Foo(self &&)
return {0};
}
int main()
{
auto &&t=create();
}
Foo is created only once, it's copy and move constructor are deleted - it is guaranteed that there will be no any copies or moves.