fork(3) download
  1. #include <iostream>
  2.  
  3. struct bar; // forward declaration
  4.  
  5. class foo { // implicitly private
  6. friend struct ::bar; // but bar is a friend
  7.  
  8. template<typename T = int>
  9. static void static_function_template() {}
  10.  
  11. template<typename T = int>
  12. void function_template() {}
  13.  
  14. template<typename T = int>
  15. class class_template {
  16. static void static_function() {}
  17. void function() {}
  18. static T static_value;
  19. T value;
  20. };
  21.  
  22. };
  23.  
  24. struct bar { // implicitly public
  25.  
  26. // some alias templates referring to class foo:
  27. template<typename T> using type01 = decltype(foo::static_function_template<T>());
  28. template<typename T> using type02 = decltype(foo::static_function_template<>());
  29. template<typename T> using type03 = decltype(foo::static_function_template<T>);
  30.  
  31. template<typename T> using type04 = decltype(foo().function_template<T>());
  32. template<typename T> using type05 = decltype(foo().function_template<>());
  33.  
  34. template<typename T> using type06 = decltype(foo::class_template<T>::static_function());
  35. template<typename T> using type07 = decltype(foo::class_template<>::static_function());
  36. template<typename T> using type08 = decltype(foo::class_template<T>::static_function);
  37.  
  38. template<typename T> using type09 = decltype(foo::class_template<T>().function());
  39. template<typename T> using type10 = decltype(foo::class_template<>().function());
  40.  
  41. // check (has direct access to bar)
  42. template<template<typename> class TT, typename T, typename = TT<T>>
  43. static void check(int) { std::cout << "> can be instantiated "; }
  44. template<template<typename> class TT, typename T>
  45. static void check(...) { std::cout << "> can NOT be instantiated "; }
  46. };
  47.  
  48. // check (has no direct access to bar)
  49. template<template<typename> class TT, typename T, typename = TT<T>>
  50. void check(int) { std::cout << "> can be instantiated "; }
  51. template<template<typename> class TT, typename T>
  52. void check(...) { std::cout << "> can NOT be instantiated "; }
  53.  
  54.  
  55.  
  56. int main() {
  57. #ifdef __clang__
  58. std::cout << "-- compiled with clang --" << std::endl;
  59. #endif
  60. #ifdef _MSC_VER
  61. std::cout << "-- compiled with MSVC --" << std::endl;
  62. #endif
  63. #ifdef __GNUC__
  64. std::cout << "-- compiled with GCC --" << std::endl;
  65. #endif
  66. std::cout << std::endl;
  67.  
  68. std::cout << " inside of bar: outside of bar: " << std::endl;
  69. std::cout << "type01 "; bar::check<bar::type01, int>(0); check<bar::type01, int>(0); std::cout << std::endl;
  70. std::cout << "type02 "; bar::check<bar::type02, int>(0); check<bar::type02, int>(0); std::cout << std::endl;
  71. std::cout << "type03 "; bar::check<bar::type03, int>(0); check<bar::type03, int>(0); std::cout << std::endl;
  72. std::cout << "type04 "; bar::check<bar::type04, int>(0); check<bar::type04, int>(0); std::cout << std::endl;
  73. std::cout << "type05 "; bar::check<bar::type05, int>(0); check<bar::type05, int>(0); std::cout << std::endl;
  74. std::cout << "type06 "; bar::check<bar::type06, int>(0); check<bar::type06, int>(0); std::cout << std::endl;
  75. std::cout << "type07 "; bar::check<bar::type07, int>(0); check<bar::type07, int>(0); std::cout << std::endl;
  76. std::cout << "type08 "; bar::check<bar::type08, int>(0); check<bar::type08, int>(0); std::cout << std::endl;
  77. std::cout << "type09 "; bar::check<bar::type09, int>(0); check<bar::type09, int>(0); std::cout << std::endl;
  78. std::cout << "type10 "; bar::check<bar::type10, int>(0); check<bar::type10, int>(0); std::cout << std::endl;
  79. std::cout << std::endl;
  80.  
  81. return 0;
  82. }
Success #stdin #stdout 0s 15240KB
stdin
Standard input is empty
stdout
-- compiled with clang --
-- compiled with GCC --

         inside of bar:              outside of bar:             
type01   > can be instantiated       > can NOT be instantiated   
type02   > can be instantiated       > can be instantiated       
type03   > can be instantiated       > can be instantiated       
type04   > can be instantiated       > can NOT be instantiated   
type05   > can be instantiated       > can be instantiated       
type06   > can NOT be instantiated   > can NOT be instantiated   
type07   > can be instantiated       > can be instantiated       
type08   > can NOT be instantiated   > can NOT be instantiated   
type09   > can NOT be instantiated   > can NOT be instantiated   
type10   > can be instantiated       > can be instantiated