fork download
  1. #include <bits/stdc++.h>
  2. #include <typeinfo>
  3. using namespace std;
  4.  
  5. #define impl(TYPE,ref){cout<<"TYPE=string";check(TYPE);cout<<"decltype(ref)=string";check(decltype(ref));cout<<"\n";}
  6.  
  7. #define check(t){\
  8.   if(std::is_rvalue_reference<t>::value)cout<<"&&";\
  9.   if(std::is_lvalue_reference<t>::value)cout<<"&";\
  10.   if(std::is_reference<t>::value)cout<<"ref";\
  11.   cout<<"; ";\
  12. }
  13.  
  14. #define combine0(a,b)a##b
  15. #define combine(a,b)combine0(a,b)
  16. #define bar(gcc_preproc_is_stupid_bullshit)bar(combine(TYPE,&ref))
  17.  
  18. using TYPE=string&;
  19. void foo(TYPE&ref){impl(TYPE,ref);}
  20.  
  21. template<class TYPE=string&> // ...
  22. void baz(TYPE&ref){impl(TYPE,ref);}
  23.  
  24. #define TYPE string&
  25. void bar(TYPE&ref){impl(TYPE,ref);}
  26.  
  27. #undef bar
  28. int main(){
  29. #define F(CODE){string s="s";printf("%s // ",#CODE);CODE;}
  30. auto foo_string_ref=foo;
  31. F( foo_string_ref(s); );
  32. F( baz<string&>( s ); );
  33. F( bar(std::move(s)); );
  34. #undef F
  35. }
Success #stdin #stdout 0s 15232KB
stdin
Standard input is empty
stdout
foo_string_ref(s); // TYPE=string&ref; decltype(ref)=string&ref; 
baz<string&>( s ); // TYPE=string&ref; decltype(ref)=string&ref; 
bar(std::move(s)); // TYPE=string&ref; decltype(ref)=string&&ref;