如何"模式匹配"模板?

use*_*445 5 c++ templates

通常在模板中你想知道整个类型,但在我的情况下我需要知道更多,并希望"分解"类型.举个例子:

template <typename Collection<typename T> >
T get_front(Collection const& c)
{
  return c.front();
}
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?注意:我需要它来自动推断类型,而不是传递类似的东西<std::vector<int>, int>

Xeo*_*Xeo 7

编辑:最后可以找到C++ 0x方式.
编辑2:我是傻了,一个办法较短C++ 98/03的方式比这一切特质的东西可以在答案的末尾.

如果您希望您的函数适用于任何仲裁标准库容器,则需要提取一些模板枪.


问题是,不同的容器采用不同数量的模板参数.std::vector,std::dequestd::list例如取2:底层项类型T和分配器类型Alloc.std::set并且std::map,另一方面分别取3和4:两者都具有的密钥类型K,地图另需值类型V,那么这两个取比较器Compare类型和分配器类型Alloc.您可以在此处获得标准库提供的所有容器类型的概述.


现在,对于模板枪.我们将使用部分专业的traits metastruct来获取基础项类型.(我使用class而不是typename纯粹的偏好.)

template<class T>
struct ContainerTraits;

// vector, deque, list and even stack and queue (2 template parameters)
template<
    template<class, class> class Container,
    class T, class Other
>
struct ContainerTraits< Container<T,Other> >{
    typedef T value_type;
};

// for set, multiset, and priority_queue (3 template parameters)
template<
    template<class, class, class> class Container,
    class T, class Other1, class Other2
>
struct ContainerTraits< Container<T,Other1,Other2> >{
    typedef T value_type;
};

// for map and multimap (4 template parameters)
template<
    template<class, class, class, class> class Container,
    class Key, class T, class Other1, class Other2
>
struct ContainerTraits< Container<Key,T,Other1,Other2> >{
    typedef Container<Key,T,Other1,Other2> ContainerT;
    // and the map returns pair<const Key,T> from the begin() function
    typedef typename ContainerT::value_type value_type;
};
Run Code Online (Sandbox Code Playgroud)

现在准备完成了,就get_front功能了!

template<class Container>
typename ContainerTraits<Container>::value_type
get_front(Container const& c){
    // begin() is the only shared access function
    // to the first element for all standard container (except std::bitset)
    return *c.begin(); 
}
Run Code Online (Sandbox Code Playgroud)

唷!就是这样!在Ideone上可以看到完整的示例.当然,有可能进一步改进,直到返回映射到a中的键的实际值std::map,或者使用容器特定的访问函数,但我只是有点懒得去做.:P


编辑
方式更容易的C++ 0x的方法是使用新的尾返回型函数的语法,其中的一个例子,可以发现在这里Ideone.


编辑2
嗯,我不知道为什么,但typedef在写这个答案时我完全没有想到嵌​​套的.我会让详细的方式作为特征类/模式匹配模板的参考.是做到一点的方式,它与我对traits类的做法基本相同,但最终不那么冗长.