#include <iostream>
#include <utility> // for std::move, std::forward
#include <type_traits> // for remove_reference_t, is_lvalue_reference_v
// C++14 version of std::move
template<typename _Tp>
constexpr decltype(auto)
move(_Tp&& __t) noexcept
{
return static_cast<std::remove_reference_t<_Tp>&&>(__t);
}
// C++14 version of std::forward for lvalues
template<typename _Tp>
constexpr decltype(auto)
forward(std::remove_reference_t<_Tp>& __t) noexcept
{
return static_cast<_Tp&&>(__t);
}
// C++14 version of std::forward for rvalues
template<typename _Tp>
constexpr decltype(auto)
forward(std::remove_reference_t<_Tp>&& __t) noexcept
{
static_assert(!std::is_lvalue_reference_v<_Tp>, "template argument substituting _Tp is an lvalue reference type");
return static_cast<_Tp&&>(__t);
}
// Test class with move and copy constructors
class Widget {
public:
Widget() { std::cout << "Widget default constructor\n"; }
Widget(const Widget&) {
std::cout << "Widget copy constructor\n";
}
Widget(Widget&&) noexcept {
std::cout << "Widget move constructor\n";
}
};
// Function to test std::forward
template <typename T>
void forward_test(T&& arg) {
Widget w = std::forward<T>(arg);
}
int main() {
// Test std::move
Widget widget1;
std::cout << "Using std::move:\n";
Widget widget2 = std::move(widget1); // Should call move constructor
// Test std::forward with lvalue
std::cout << "\nUsing std::forward with lvalue:\n";
Widget widget3;
forward_test(widget3); // Should call copy constructor
// Test std::forward with rvalue
std::cout << "\nUsing std::forward with rvalue:\n";
forward_test(Widget()); // Should call move constructor
return 0;
}