Last active
February 18, 2016 09:37
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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