Q:

Ways to generalize C++ code with different similar types

Currently I have the following code:
static void markPoolsFree(const TNetgroupPools &group_info, TObjectID netiface) {
    for (size_t i = 0; i<group_info.public_pools.length();i ++ ) {
        SDK::revokeIPPoolFromNetworkInterface(group_info.public_pools[i],netiface);
    }

    for (size_t i =0 ; i<group_info.private_pool.length(); i++) {
        SDK::revokeIPPoolFromNetworkInterface(group_info.private_pool[i].pool_id,
                                              netiface);
    }
}

which has basically the same logic, but differents in types group_info.public_pools[i] and group_info.private_pool[i], that's why in second loop we have to add .pool_id member call. These types are different and don't have any relationships.
I want to rewrite this code to make it more general, for example something like this (sketch):
// template function
template <typename Container, typename PredArgs>
static void revokeIPPool(const Container &pool, TObjectID netiface,
                         bool (*pred)(PredArgs pool_id, PredArgs netiface_id))
{
     for (size_t i = 0; i < pool.length(); ++i) {
         if (pred(pool[i], netiface)) {
             SDK::revokeIPPoolFromNetworkInterface(pool[i], netiface);
         }

     }
}

// calling code
static void markPoolsFree(const TNetgroupPools &group_info, TObjectID netiface) {
    revokeIPPool(group_info.public_pools, netiface, SDK::isPredicateTrue);
    revokeIPPool(group_info.private_pool, netiface, SDK::isPredicateTrue);
}

But the problem is in different types for public_pools and private_pool.
Question:
Could you give all ways how is possible to generalize this code with examples? I need C++03 code, but C++11/C++14 is acceptable.
My thoughts:

Instead of SDK::revokeIPPoolFromNetworkInterface make wrapperIPPool with overloads for both types and call SDK::revokeIPPoolFromNetworkInterface internally.
Overload revokeIPPool for both types (but it's code duplication, no improvement against original code)
Partial function template specialization for revokeIPPool (is this possible?)
Full function template specialization for revokeIPPool
Wrap function revokeIPPool in class and make partial class template specialization.

Questions:

Wich of my thoughts are correct?
What's about advantages and shortcomings?
Which is more idiomatic for C++03 or C++11?
Is there other solutions?

A:

In C++03 I'd use template specialization on a traits class. (The main reason for going through a traits class, rather than using direct function specialisation, or overload is that you can perform partial template specialisation for classes, but not functions - and while its not needed here, it may be something that is useful later )
static void markPoolsFree(const TNetgroupPools &group_info, TObjectID netiface) {
    markPoolsFreeImpl(group_info.public_pools, netiface);
    markPoolsFreeImpl(group_info.private_pools, netiface);
}

template<typename T>
static void markPoolsFreeImpl(POOLS pools, TObjectID netiface) {
    for (size_t i = 0; i<pools.length();i ++ ) {
       PoolId poolid = PoolListTrait<POOLS>::get(pools,i);
       SDK::revokeIPPoolFromNetworkInterface(poolid,netiface);
    }
}

template<typename T> class PoolListTrait {};

template<> class PoolListTrait<PublicPoolList> {
  static PoolId get(PublicPoolList pools, int i) { return pools[i]; }
}

template<> class PoolListTrait<PrivatePoolList> {
  static PoolId get(PrivatePoolList pools, int i) { return pools[i].pool_id; }
}

