This test:
#include <type_traits>
#include <typeinfo>
#include <iostream>
#ifndef _MSC_VER
# include <cxxabi.h>
#endif
#include <memory>
#include <string>
#include <cstdlib>
#include <vector>
template <typename T>
std::string
type_name()
{
typedef typename std::remove_reference<T>::type TR;
std::unique_ptr<char, void(*)(void*)> own
(
#ifndef _MSC_VER
abi::__cxa_demangle(typeid(TR).name(), nullptr,
nullptr, nullptr),
#else
nullptr,
#endif
std::free
);
std::string r = own != nullptr ? own.get() : typeid(TR).name();
if (std::is_const<TR>::value)
r += " const";
if (std::is_volatile<TR>::value)
r += " volatile";
if (std::is_lvalue_reference<T>::value)
r += "&";
else if (std::is_rvalue_reference<T>::value)
r += "&&";
return r;
}
template <int N>
struct member
{
member()
{
std::cout << type_name<member>() << "()\n";
}
~member()
{
std::cout << "~" << type_name<member>() << "()\n";
}
member(member const& x)
{
std::cout << type_name<member>()
<< "(" << type_name<decltype(x)>() << ")\n";
}
member& operator=(member const& x)
{
std::cout << type_name<member>() << "::operator=("
<< type_name<decltype(x)>() << ")\n";
return *this;
}
member(member&& x)
{
std::cout << type_name<member>()
<< "(" << type_name<decltype(x)>() << ")\n";
}
member& operator=(member&& x)
{
std::cout << type_name<member>() << "::operator=("
<< type_name<decltype(x)>() << ")\n";
return *this;
}
};
int
main()
{
std::vector<member<1>> v;
v.reserve(10);
member<1> m;
std::cout << "\npush_back an lvalue\n";
v.push_back(m);
std::cout << "\nemplace_back an lvalue\n";
v.emplace_back(m);
std::cout << "\npush_back an xvalue\n";
v.push_back(std::move(m));
std::cout << "\nemplace_back an xvalue\n";
v.emplace_back(std::move(m));
std::cout << "\npush_back a prvalue\n";
v.push_back(member<1>{});
std::cout << "\nemplace_back an prvalue\n";
v.emplace_back(member<1>{});
std::cout << "\nDone\n";
}
For me outputs:
member<1>()
push_back an lvalue
member<1>(member<1> const&)
emplace_back an lvalue
member<1>(member<1> const&)
push_back an xvalue
member<1>(member<1>&&)
emplace_back an xvalue
member<1>(member<1>&&)
push_back a prvalue
member<1>()
member<1>(member<1>&&)
~member<1>()
emplace_back an prvalue
member<1>()
member<1>(member<1>&&)
~member<1>()
Done
~member<1>()
~member<1>()
~member<1>()
~member<1>()
~member<1>()
~member<1>()
~member<1>()
I.e. I would not expect any difference whatsoever.