Из POV пользователей вашей оболочки лучше всего было бы, если бы они вызывали либо перегруженную функцию, либо шаблон функции (члена), которому они передали объект соответствующего типа и который затем волшебным образом сделал бы правильноевещь для этого типа.То есть лучше всего иметь функцию getData(unsigned int colIndex, T&)
для любого типа T
, поддерживаемого вашим классом (или Oracle API), который будет определять необходимый размер буфера, выделять буфер, определять правильное перечисление и вызыватьфункция Oracle API.
Я уверен, что вы можете проработать большинство деталей, возможно, за исключением того, как сопоставить тип с enum
, поэтому я постараюсь выделить это.
По сути, я вижу две возможности для этого, одна из которых (использование списка времени компиляции) лучше подходит, если у вас есть много типов для поддержки, в то время как другую (использование черт) нужно использоватьесли есть что-то более специфичное для типа, чем просто отображение типа на enum
.
Метод черт довольно прост в использовании, но утомителен, если у вас много типов:
template<typename T>
struct get_data_buffer_traits;
template<>
struct get_data_buffer_traits<int> {
Type type OCCIINT;
};
template<>
struct get_data_buffer_traits<float> {
Type type OCCIBFLOAT;
};
Затем вы можете отобразить тип, переданный вашему шаблону, как T
в правом enum
значение с использованием get_data_buffer_traits<T>::type
.
Этот шаблон признаков также является местом, куда вы можете поместить любую другую специфическую для типа операцию, которая может понадобиться вашей универсальной функции поиска данных (например, преобразование между тем, что находится в буфере, и фактическим типом, если это не является прямымВперед)Если вам больше нечего добавить в эти черты, вы можете использовать макрос, чтобы упростить их определение:
#define DEFINE_GET_DATA_BUFFER_TRAITS(Type_,Enum_) \
template<> struct get_data_buffer_traits<Type_> { Type type Enum_; };
DEFINE_GET_DATA_BUFFER_TRAITS(int , OCCIINT );
DEFINE_GET_DATA_BUFFER_TRAITS(float, OCCIBFLOAT);
...
#undef DEFINE_GET_DATA_BUFFER_TRAITS
Однако, если это так, вы могли бы также создать время компиляциикарта, которая отображает два и поиск (во время компиляции) для правильного значения enum
.Если у вас нет библиотеки метаданных шаблонов, которая обеспечивает это, вот схема для идеи, как сделать это самостоятельно:
// Beware, brain-compiled code ahead!
struct nil {};
template< typename HType
, Type HEnum
, class T >
struct set_data_buffer_type_map_node {
typedef HType head_type
enum { head_enum = HEnum };
typedef T tail_type;
};
typedef
set_data_buffer_type_map_node< int , OCCIINT
set_data_buffer_type_map_node< float, OCCIBFLOAT
...
nil
> > // either count or keep adding these until compiler accepts :)
set_data_buffer_type_map;
template< typename T, class Map >
struct getter {
// recurse towards tail
Type get_enum() { return getter<T,typename Map::tail_type>::get_enum(); }
};
template< typename T, Type HEnum, class Tail >
struct getter< T, set_data_buffer_type_map<T,HEnum,Tail> > {
// current node has T as HType
Type get_enum() { return set_data_buffer_type_map<T,HEnum,Tail>::head_enum; }
};
template< typename T, typename HType, Type HEnum, >
struct getter< T, set_data_buffer_type_map<T,HEnum,nil> > {
// no function here, so compile-time error
};
template< typename T>
Type get_type_enum()
{
return getter<T, set_data_buffer_type_map>::get_enum();
}
(Примечание: это просто схема. Я даже не имеюпопытался скомпилировать его.)