Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting template type at runtime

I've got the following method that gets a vector of C-style structs and processes its elements one at a time.

I wish to extend it to receive more types of struct without duplicating my code.

Since all types of structs will contain the same field names, it would be most elegant to implement this new requirement using templates.

However, I cannot decide how to pass the second argument to the write_db function; that argument which is an enum per struct type—is there any option to acquire this at runtime?

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);
}

I thought about adding the enum value as constant for each instance of struct but I hope to find a better approach that wouldn't require changing my basic struct format.

like image 701
Zohar81 Avatar asked Jan 05 '16 07:01

Zohar81


2 Answers

If you don't want to add a member, you can provide a "traits" type.

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);
    }
}
like image 191
molbdnilo Avatar answered Nov 09 '22 11:11

molbdnilo


Have a type field on every class that is POLICY-able (if you get my meaning), of which foo is an example:

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

Then use write_db(item.key1, POLICY::type) as appropriate.

like image 29
Bathsheba Avatar answered Nov 09 '22 10:11

Bathsheba