- c : Given a pointer type how can one recover the pointee type?
- struct Field
- {
- template<class T> T Value() const
- {
- // ???
- }
- template<class S> S SimpleValue() const
- {
- return *reinterpret_cast<const S *>(GetVoidPointerToTheActualValue());
- }
- template<class P> const P *PointerValue() const
- {
- return reinterpret_cast<const P *>(GetVoidPointerToTheActualValue());
- }
- };
- 1> playmssqlce.cpp
- 1>c:devinternalplaymssqlceplaymssqlce.cpp(75): error C2668: 'sqlserver::Field::Value' : ambiguous call to overloaded function
- 1> c:devinternalplaymssqlcesqlserverfield.h(19): could be 'std::tr1::enable_if<_Test,_Type> sqlserver::Field::Value<LPCWSTR>(void) const'
- 1> with
- 1> [
- 1> _Test=false,
- 1> _Type=LPCWSTR
- 1> ]
- 1> c:devinternalplaymssqlcesqlserverfield.h(18): or 'std::tr1::enable_if<_Test,_Type> sqlserver::Field::Value<LPCWSTR>(void) const'
- 1> with
- 1> [
- 1> _Test=true,
- 1> _Type=LPCWSTR
- 1> ]
- 1> while trying to match the argument list '(void)'
- struct Field
- {
- template<class T> typename enable_if<is_pointer<T>::value, T>::type Value() const { return PointerValue(); }
- template<class T> typename enable_if<!is_pointer<T>::value, T>::type Value() const { return SimpleValue(); }
- template<class T> T SimpleValue() const { return *reinterpret_cast<const T *>(GetVoidPointerToTheActualValue()); }
- template<class T> const T *PointerValue() const { return reinterpret_cast<const T *>(GetVoidPointerToTheActualValue()); }
- };
- 1> playmssqlce.cpp
- 1>c:devinternalplaymssqlcesqlserverfield.h(18): error C2783: 'const T *sqlserver::Field::PointerValue(void) const' : could not deduce template argument for 'T'
- 1> c:devinternalplaymssqlcesqlserverfield.h(42) : see declaration of 'sqlserver::Field::PointerValue'
- 1> c:devinternalplaymssqlceplaymssqlce.cpp(75) : see reference to function template instantiation 'const wchar_t *sqlserver::Field::Value<const wchar_t*>(void) const' being compiled
- template<class T> typename enable_if<is_pointer<T>::value, T>::type Value() const { return PointerValue<typename std::remove_pointer<T>::type>(); }
- template<class T> typename enable_if<!is_pointer<T>::value, T>::type Value() const { return SimpleValue<T>(); }
- struct Field {
- /*Other methods of Field*/
- template<class T>
- typename std::enable_if<std::is_pointer<T>::value, T>::type Value() const {
- return this->PointerValue<typename std::remove_pointer<T>::type>();
- }
- template<class T>
- typename std::enable_if<!std::is_pointer<T>::value, T>::type Value() const {
- return this->SimpleValue<T>();
- }
- };
- typename std::enable_if<
- std::is_pointer<T>::value, typename
- std::add_const<typename
- std::remove_pointer<T>::type
- >::type*
- >::type Value() const;
- template < typename T >
- struct getValue
- {
- static T apply() { default behavior }
- };
- template < typename T>
- struct getValue< T * >
- {
- static T * apply() { behavior for pointer types }
- };
- #include <iostream>
- namespace detail { template < typename T > struct getValue; }
- class Field
- {
- public:
- void * getVoidPointerToTheActualValue() const;
- template< class T >
- typename detail::getValue< T >::result_type value() const;
- private:
- void * actualValue_;
- };
- namespace detail {
- template < typename T >
- struct getValue
- {
- typedef T result_type;
- static result_type apply( Field const & f )
- {
- std::cout << "simpleValue" << 'n';
- return *reinterpret_cast< const T * >(
- f.getVoidPointerToTheActualValue() );
- }
- };
- template < typename T >
- struct getValue< T * >
- {
- typedef T const * result_type;
- static result_type apply( Field const & f )
- {
- std::cout << "pointerValue" << 'n';
- return reinterpret_cast< const T * >(
- f.getVoidPointerToTheActualValue() );
- }
- };
- } //namespace detail
- void * Field::getVoidPointerToTheActualValue() const
- {
- return actualValue_;
- }
- template< class T >
- typename detail::getValue< T >::result_type Field::value() const
- {
- return detail::getValue< T >::apply( *this );
- }
- int main()
- {
- Field f;
- f.value< int >(); //prints "simpleValue"
- f.value< int * >(); //prints "pointerValue"
- }