fork(1) download
  1. #include <iostream>
  2. #include <type_traits>
  3.  
  4.  
  5. // Wrapper #######################################
  6.  
  7. template<class T>
  8. struct Wrapper {typedef T WrappedType;};
  9.  
  10. template<class T, class Enable=void>
  11. struct IsWrapper: std::false_type {};
  12.  
  13. template<class T>
  14. struct IsWrapper<Wrapper<T> >: std::true_type {};
  15.  
  16.  
  17. // WrapperTraits #######################################
  18.  
  19. template<
  20. class T,
  21. bool HasWrapper=
  22. IsWrapper<T>::value && IsWrapper<typename T::WrappedType>::value>
  23. struct GetRootType {
  24. static_assert(IsWrapper<T>::value,"T is not a wrapper type");
  25.  
  26. typedef typename T::WrappedType RootType;
  27. };
  28.  
  29. template<class T>
  30. struct GetRootType<T,true> {
  31. typedef typename GetRootType<typename T::WrappedType>::RootType RootType;
  32. };
  33.  
  34. template<class T>
  35. struct WrapperTraits {
  36. typedef typename GetRootType<T>::RootType RootType;
  37. };
  38.  
  39.  
  40. // Test function #######################################
  41.  
  42. void f(int) {
  43. std::cout<<"int"<<std::endl;
  44. }
  45.  
  46. // #define ROOT_TYPE_ACCESSOR WrapperTraits // <-- Causes compilation error.
  47. #define ROOT_TYPE_ACCESSOR GetRootType // <-- Compiles without error.
  48.  
  49. template<class T>
  50. auto f(T) ->
  51. typename std::enable_if<
  52. std::is_same<int,typename ROOT_TYPE_ACCESSOR<T>::RootType>::value
  53. >::type
  54. {
  55. typedef typename ROOT_TYPE_ACCESSOR<T>::RootType RootType;
  56.  
  57. std::cout<<"Wrapper<...<int>...>"<<std::endl;
  58. f(RootType());
  59. }
  60.  
  61.  
  62. int main() {
  63. f(Wrapper<int>());
  64. return 0;
  65. }
Success #stdin #stdout 0s 3096KB
stdin
Standard input is empty
stdout
Wrapper<...<int>...>
int