Don't like ads? PRO users don't see any ads ;-)
Guest

Untitled

By: a guest on May 8th, 2012  |  syntax: None  |  size: 4.24 KB  |  hits: 9  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. c  : Given a pointer type how can one recover the pointee type?
  2. struct Field
  3. {
  4.   template<class T> T Value() const
  5.   {
  6.     // ???
  7.   }
  8.   template<class S> S SimpleValue() const
  9.   {
  10.     return *reinterpret_cast<const S *>(GetVoidPointerToTheActualValue());
  11.   }
  12.   template<class P> const P *PointerValue() const
  13.   {
  14.     return reinterpret_cast<const P *>(GetVoidPointerToTheActualValue());
  15.   }
  16. };
  17.        
  18. 1>  playmssqlce.cpp
  19. 1>c:devinternalplaymssqlceplaymssqlce.cpp(75): error C2668: 'sqlserver::Field::Value' : ambiguous call to overloaded function
  20. 1>          c:devinternalplaymssqlcesqlserverfield.h(19): could be 'std::tr1::enable_if<_Test,_Type> sqlserver::Field::Value<LPCWSTR>(void) const'
  21. 1>          with
  22. 1>          [
  23. 1>              _Test=false,
  24. 1>              _Type=LPCWSTR
  25. 1>          ]
  26. 1>          c:devinternalplaymssqlcesqlserverfield.h(18): or       'std::tr1::enable_if<_Test,_Type> sqlserver::Field::Value<LPCWSTR>(void) const'
  27. 1>          with
  28. 1>          [
  29. 1>              _Test=true,
  30. 1>              _Type=LPCWSTR
  31. 1>          ]
  32. 1>          while trying to match the argument list '(void)'
  33.        
  34. struct Field
  35. {
  36.   template<class T> typename enable_if<is_pointer<T>::value, T>::type Value() const { return PointerValue(); }
  37.   template<class T> typename enable_if<!is_pointer<T>::value, T>::type Value() const { return SimpleValue(); }
  38.   template<class T> T SimpleValue() const         { return *reinterpret_cast<const T *>(GetVoidPointerToTheActualValue()); }
  39.   template<class T> const T *PointerValue() const { return reinterpret_cast<const T *>(GetVoidPointerToTheActualValue()); }
  40. };
  41.        
  42. 1>  playmssqlce.cpp
  43. 1>c:devinternalplaymssqlcesqlserverfield.h(18): error C2783: 'const T *sqlserver::Field::PointerValue(void) const' : could not deduce template argument for 'T'
  44. 1>          c:devinternalplaymssqlcesqlserverfield.h(42) : see declaration of 'sqlserver::Field::PointerValue'
  45. 1>          c:devinternalplaymssqlceplaymssqlce.cpp(75) : see reference to function template instantiation 'const wchar_t *sqlserver::Field::Value<const wchar_t*>(void) const' being compiled
  46.        
  47. template<class T> typename enable_if<is_pointer<T>::value, T>::type Value() const { return PointerValue<typename std::remove_pointer<T>::type>(); }
  48. template<class T> typename enable_if<!is_pointer<T>::value, T>::type Value() const { return SimpleValue<T>(); }
  49.        
  50. struct Field {
  51.   /*Other methods of Field*/
  52.   template<class T>
  53.   typename std::enable_if<std::is_pointer<T>::value, T>::type Value() const {
  54.     return this->PointerValue<typename std::remove_pointer<T>::type>();
  55.   }
  56.   template<class T>
  57.   typename  std::enable_if<!std::is_pointer<T>::value, T>::type Value() const {
  58.     return this->SimpleValue<T>();
  59.   }
  60.  
  61. };
  62.        
  63. typename std::enable_if<
  64.     std::is_pointer<T>::value, typename
  65.     std::add_const<typename
  66.         std::remove_pointer<T>::type
  67.     >::type*
  68. >::type Value() const;
  69.        
  70. template < typename T >
  71. struct getValue
  72. {
  73.     static T apply() { default behavior }
  74. };
  75.  
  76. template < typename T>
  77. struct getValue< T * >
  78. {
  79.     static T * apply() { behavior for pointer types }
  80. };
  81.        
  82. #include <iostream>
  83.  
  84. namespace detail { template < typename T > struct getValue; }
  85.  
  86. class Field
  87. {
  88.   public:
  89.     void * getVoidPointerToTheActualValue() const;
  90.  
  91.     template< class T >
  92.     typename detail::getValue< T >::result_type value() const;
  93.  
  94.   private:
  95.     void * actualValue_;
  96. };
  97.  
  98. namespace detail {
  99.  
  100. template < typename T >
  101. struct getValue
  102. {
  103.     typedef T result_type;
  104.  
  105.     static result_type apply( Field const & f )
  106.     {
  107.         std::cout << "simpleValue" << 'n';
  108.         return *reinterpret_cast< const T * >(
  109.                 f.getVoidPointerToTheActualValue() );
  110.     }
  111. };
  112.  
  113. template < typename T >
  114. struct getValue< T * >
  115. {
  116.     typedef T const * result_type;
  117.  
  118.     static result_type apply( Field const & f )
  119.     {
  120.         std::cout << "pointerValue" << 'n';
  121.         return reinterpret_cast< const T * >(
  122.                 f.getVoidPointerToTheActualValue() );
  123.     }
  124. };
  125.  
  126. } //namespace detail
  127.  
  128.  
  129. void * Field::getVoidPointerToTheActualValue() const
  130. {
  131.     return actualValue_;
  132. }
  133.  
  134. template< class T >
  135. typename detail::getValue< T >::result_type Field::value() const
  136. {
  137.     return detail::getValue< T >::apply( *this );
  138. }
  139.  
  140.  
  141. int main()
  142. {
  143.     Field f;
  144.     f.value< int >();   //prints "simpleValue"
  145.     f.value< int * >(); //prints "pointerValue"
  146. }