Дано:
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());
}
};
Как реализовать метод Field::Value<T>()
, чтобы компилятор автоматически отправлял:
Field::PointerValue<P>
, если T
действительноP*
Field::SimpleValue<S>
в противном случае
Кроме того, гарантируется, что T
не является ни ссылкой, ни указателем на указатель.
Спасибо.
РЕДАКТИРОВАТЬ
@ Grizzly - я попробовал ваше предложение, к сожалению, оно не сработало во время компиляции Value<LPCWSTR>()
:
1> playmssqlce.cpp
1>c:\dev\internal\playmssqlce\playmssqlce.cpp(75): error C2668: 'sqlserver::Field::Value' : ambiguous call to overloaded function
1> c:\dev\internal\playmssqlce\sqlserverfield.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:\dev\internal\playmssqlce\sqlserverfield.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)'
Мне непонятно почему, потому что ваш совет кажется правильным.Кстати, я использую Visual Studio 2010.
EDIT2
После исправления глупой ошибки у меня все еще есть проблемы.Итак, вот что у меня есть:
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()); }
};
Я пытаюсь скомпилировать f.Value<const wchar_t *>()
, но получаю это:
1> playmssqlce.cpp
1>c:\dev\internal\playmssqlce\sqlserverfield.h(18): error C2783: 'const T *sqlserver::Field::PointerValue(void) const' : could not deduce template argument for 'T'
1> c:\dev\internal\playmssqlce\sqlserverfield.h(42) : see declaration of 'sqlserver::Field::PointerValue'
1> c:\dev\internal\playmssqlce\playmssqlce.cpp(75) : see reference to function template instantiation 'const wchar_t *sqlserver::Field::Value<const wchar_t*>(void) const' being compiled
Что я делаю не так сейчас?
Спасибо.
РЕДАКТИРОВАТЬ3
Глупый меня.Заметил изменение Гризли:
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>(); }
Работает сейчас.