在我的工作中我们做了很多结对编程,并且我编写了一个只接受SINGLE类型或其派生的容器的函数,但是我的同事担心它会失败代码审查,因为它看起来非常丑陋和说有更好的方法:
这里是签名,Fruit类是我为这个帖子重命名为Fruit的基类:
template <class Container>
typename enable_if<is_base_of<Fruit, typename remove_pointer<typename Container::value_type>::type>::value, void>::type
processFruits(container& fruits)
{
//process the elements and change them if needed. thats why no const
}
它的作用是:返回void并启用函数IF它是一个容器和容器内的类型是Fruit和/或派生的fruit。我还使用了std :: remove_pointer,因为我需要知道指针的“类型”(容器很可能有指针)。
这个编译并按预期工作,但正如我所说,我不知道它是最好的方法,它似乎太冗长,可能会削减代码审查。
编辑:这也接受模板化的类,不必是容器。有没有办法可以限制它只接受STL容器?
任何其他想法或它是否很好? 提前谢谢。
答案 0 :(得分:1)
阅读时有点可怕。
对于初学者来说,您不需要说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容器”,但是您要定义它。要正确执行此操作,您需要一个测试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 */>
{ };