Home > Software design >  How to template on a container type
How to template on a container type

Time:06-29

I have two functions

template <class T> void foo(std::vector<T>* p)

and

template <class T> void foo(std::valarray<T>* p)

The code in the function bodies is identical. Is there a clever way of writing the template so I can avoid the duplication? Something like

template <class T, class Container> void foo(Container<T>* p)

I'm using C 14.

I only want to allow Container to be either std::vector or std::valarray.

CodePudding user response:

Note: you cannot really specialize on std::vector<> and std::valarray<>, but you can say, for the given (deduced) T, you expect std::vector<T> or std::valarray<T>. Thus aliases will also be resolved.

The trick is, you templetize for a template class C and a type T (and possibly further parameters, as in std), then use std::enable_if<> that only resolves (to void in this case) when either std::vector<T> or std::valarray<T> was resolved.

Also note, you might want to allow custom allocators et. al., i.e., instead of a single T, it's recommended to use typename... Ts for the container.

#include <iostream>
#include <vector>
#include <valarray>
#include <type_traits>

template<template<class...> class C, typename T>
auto foo(C<T>* arg) -> std::enable_if_t<std::is_same<C<T>, std::vector<T>>::value || std::is_same<C<T>, std::valarray<T>>::value>
{
}

int main() {
    std::vector<int> v;
    std::valarray<int> va;
    //std::pair<int, int> p; // this should fail
    foo(&v);
    foo(&va);
    //foo(&p); // this fails as expected
    return 0;
}

CodePudding user response:

You can also create type traits only for your case.

template <typename T>
struct is_vector_or_valarray : std::false_type {};

template<class T>
struct is_vector_or_valarray<std::vector<T>> : std::true_type {};

template<class T>
struct is_vector_or_valarray<std::valarray<T>> : std::true_type {};

template<typename C, typename = std::enable_if_t<is_vector_or_valarray<C>::value>>
void foo(C* p) {}

Demo

  • Related