2016-01-05 2 views
8

У меня есть следующий метод, который получает вектор структур C-стиля и обрабатывает его элементы по одному за раз.Получение типа шаблона во время выполнения

Я хочу расширить его, чтобы получать больше типов структуры без дублирования моего кода.

Поскольку все типы структур будут содержать одинаковые имена полей, было бы очень элегантно реализовать это новое требование с использованием шаблонов.

Однако я не могу решить, как передать второй аргумент функции write_db; этот аргумент, который является перечислением для типа структуры —, есть ли возможность приобрести его во время выполнения?

enum policy_types { 
    POLICY_TYPE_A, 
    POLICY_TYPE_B, 
    ... 
}; 

// old implementation - suitable for single struct only 
int policyMgr::write_rule(std::vector <struct policy_type_a> & list) { 
    //conduct boring pre-write check 
    //... 

    for (auto & item : list) { 
     int ret = write_db(item.key1, POLICY_TYPE_A_ENUM, &item.blob); 
} 

//new implementation - suitable for multiple structs. 
template <POLICY> 
int policyMgr::write_rule(std::vector <POLICY> & list) { 
    for (auto & item : list) { 
     int ret = write_db(item.key1, type(POLICY) /* how can i get enum according to template type */, &item.blob); 
} 

Я думал о добавлении значения перечисления в качестве постоянная для каждого экземпляра структуры, но я надеюсь найти лучший подход, который не требует изменений моего основного формата структуру.

ответ

10

Если вы не хотите добавлять участника, вы можете указать тип «признаков».

template<typename P> 
struct PolicyTraits {}; 

template<> 
struct PolicyTraits<policy_type_a> 
{ 
    static enum { Type = POLICY_TYPE_A }; 
}; 

template<> 
struct PolicyTraits<policy_type_b> 
{ 
    static enum { Type = POLICY_TYPE_B }; 
}; 

template <typename A> 
int policyMgr::write_rule(const std::vector<A> & list) { 
    for (const auto & item : list) { 
     int ret = write_db(item.key1, PolicyTraits<A>::Type, &item.blob); 
    } 
} 
+0

Да, это более элегантный (и стандартный для C++) способ: это, в отличие от моего решения, не загрязняет класс 'A'. Плюс один. – Bathsheba

+0

Я бы избегал имени 'type' for ** value ** в свойствах/политике. – Jarod42

+0

, но это не сработает во время работы! если вектор специализирован базовым классом политики и содержит подтипы производной политики ... шаблон получит только черту специализации своего вектора – barney

3

Есть поле типа на каждом классе, который POLICY -able (если вы получите мое значение), из которых foo пример:

struct foo 
{ 
    /*your other bits*/ 
    static const policy_types type = POLICY_TYPE_whatever; /*older standards 
            might require definition in a source file */. 
}; 

Затем используйте write_db(item.key1, POLICY::type) в зависимости от обстоятельств.

Смежные вопросы