如何编写模板函数模板作用于嵌套的stl容器并限制最内层类型

时间:2016-11-30 16:38:05

标签: c++ templates

我目前正在尝试使用stl容器模板的模板

template <template <typename, typename > class Container, typename element, typename Allocator>
void printsize (Container<element, Allocator> & a){
    std::cout<<"container size: "<<a.size()<<std::endl;
};


int main(){

    std::vector<double> testvector;

    for(int i = 0; i < 4; ++i){
        testvector.push_back((double) i);
    }

    printsize(testvector);

    std::list<std::vector<double> > testlist;
    for(int i = 0; i < 8; ++i){
        testlist.push_back(testvector);
    }
    printsize(testlist);
}

输出正确

container size: 4
container size: 8

我试图将函数接受的模板类型的范围限制为

stl::container<double>.

如果我尝试这样的话:

template <template <typename, typename > class Container, typename Allocator>
void printsize (Container<double , Allocator> & a){
    std::cout<<"container size: "<<a.size()<<std::endl;
};

会让编译器抱怨

std::vector<int>

容器按预期方式,但它不再适用于

std::list<std::vector< double> >

因为,嗯,double是与std :: vector

不同的类型

但是,我希望我的函数对任意stl容器和stl容器的stl容器(等等)只对特定的“base”类型起作用。

这背后的原因是我不想使用大量的重载。基本上我想要实现的是编写一些函数

B dosomestuff(A a){
    B b =  someWorkDoneOnA(a);
    return b;
}

stl::container<A> dosomestuff(stl::container<B> myContainer){
    B newContainerElement;
    stl::container<A> outputContainer;
    for(auto i& : myContainer){
         newContainerElement = dosomestuff(i);
         outputContainer.push_back(newContainerElement);
    }
    return outputContainer;
};

到目前为止,我有一个函数作用于B的向量并创建A的向量,重载了另一个函数,该函数作用于B的向量向量并输出A向量的向量(调用前一个函数)等等(老实说,现在就是这样,我认为我不会需要更多,但谁知道?)。它实际上是相同的代码片段(类型声明除外),即WET。

1 个答案:

答案 0 :(得分:1)

让我们从“N的嵌套容器”的类型特征开始(其中N == 0是B)

template <typename T>
struct is_B : std::false_type;

template <template <typename, typename > class Container, typename Element, typename Allocator>
struct is_B<Container<Element, Allocator>> : std::is_B<Element>;

template <>
struct is_B<B> : std::true_type;

然后,您可以使用enable_if:

扩充工作模板
template <template <typename, typename > class Container, typename Element, typename Allocator>
void printThings(Container<std::enable_if<is_B<Element>::value, Element>, Allocator>) ...

这让我们半途而废。然后我们创建一个集合类型构造函数模板

template <typename T>
struct Bs_to_As {};

template <template <typename, typename > class Container, typename Element, typename Allocator>
struct Bs_to_As<Container<Element, Allocator>> { typedef Container<Bs_to_As<Element>::type, Allocator> type; }

template <>
struct Bs_to_As<B> { typedef A type; }

template <template <typename, typename > class Container, typename Element, typename Allocator>
Container<Bs_to_As<Element>, Allocator> doStuff(Container<Element, Allocator> myContainer)
{ ... }