读起来有点可怕。
对于初学者来说,你不需要说enable_if<B, void>
你可以说enable_if<B>
并使用默认的模板参数。
您可以轻松地将其拆分为单独的部分:
template <class T>
struct is_fruity
: is_base_of<Fruit, T>
{ };
template <class Container, typename Value = typename Container::value_type>
struct is_fruit_container
: is_fruity<typename remove_pointer<Value>::type>>
{ };
template<class Container>
typename enable_if<is_fruit_container<Container>::value>::type
processFruits(Container& fruits)
{
//process the elements and change them if needed. thats why no const
}
如果你有一个支持别名模板的编译器,你可以让它更容易阅读:
template<typename Cond>
using Require = typename enable_if<Cond::value>::type;
template<class Container>
Require<is_fruit_container<Container>>
processFruits(Container& fruits)
{
//process the elements and change them if needed. thats why no const
}
这也接受模板类,不必是容器。有没有办法可以限制它只接受 STL 容器?
我不确定“模板类”是什么意思,它只接受嵌套value_type
类型的类型,该类型是派生自该类型的类型Fruit
或指向此类类型的指针,它不必是模板。要将其限制为“STL 容器”,您需要编写一个特征来识别“STL 容器”,但是您想定义它。要正确地做到这一点,您需要一个 trait 来测试begin()
、end()
、size()
成员以及容器要求指定的所有嵌套类型iterator
、value_type
、 等。
template<typename C, typename Chead, typename... Ctail>
struct static_and
{
static const bool value = C::value && static_and<Chead, Ctail...>::value;
};
template<typename C>
struct static_and<C>
{
static const bool value = C::value;
};
template<typename C>
struct is_container
: static_and<has_begin<C>, has_end<C>, has_iterator<C>, has_value_type<C> /* etc */>
{ };