Skip to content

Instantly share code, notes, and snippets.

@oliora
Last active February 18, 2016 09:37
Show Gist options
  • Save oliora/285645f46b331cce0cc3 to your computer and use it in GitHub Desktop.
Save oliora/285645f46b331cce0cc3 to your computer and use it in GitHub Desktop.
Print value category and constness of a universal reference for all the different argument options
#include <iostream>
#include <type_traits>
#include <utility>
namespace {
struct Func
{
Func() = default;
Func(const Func&) = delete;
Func& operator= (const Func&) = delete;
Func(Func&&) = delete;
Func& operator= (Func&&) = delete;
const char *operator() () & { return "L_value"; }
const char *operator() () && { return "R_value"; }
const char *operator() () const & { return "const L_value"; }
const char *operator() () const && { return "const R_value"; }
};
inline const char *category_name(bool lvalue_ref, bool rvalue_ref)
{
if (lvalue_ref)
return "L_value reference";
if (rvalue_ref)
return "R_value reference";
return "value";
}
#define TYPE_INFO(type__) \
(std::is_lvalue_reference<type__>::value ? (std::is_const<typename std::remove_reference<type__>::type>::value ? "const L_value ref" : "L_value ref") \
: std::is_rvalue_reference<type__>::value ? (std::is_const<typename std::remove_reference<type__>::type>::value ? "const R_value ref" : "R_value ref") \
: std::is_const<type__>::value ? "const value" : "value")
template<class F>
void func(F && f)
{
std::cout
<< "forward<F>: " << (std::forward<F>(f)()) << "\n"
<< "forward<decltype(f)>: " << (std::forward<decltype(f)>(f)()) << "\n"
<< "forward<F&&>: " << (std::forward<F&&>(f)()) << "\n"
<< "std::move: " << (std::move(f)()) << "\n"
<< "nothing: " << (f()) << "\n"
;
std::cout
<< "F: " << TYPE_INFO(F) << "\n"
<< "decltype(f): " << TYPE_INFO(decltype(f)) << "\n"
<< "F&&: " << TYPE_INFO(F&&) << "\n"
;
}
}
int main()
{
Func f1{};
std::cout << "L_value:\n";
func(f1);
std::cout << "\nR_value:\n";
func(std::move(f1));
std::cout << "\nR_value:\n";
func(Func{});
const Func f2{};
std::cout << "\nconst L_value:\n";
func(f2);
std::cout << "\nconst R_value:\n";
func(std::move(f2));
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment