我正在寻找有关如何使用C ++中的模板设计多类型通用算法的指南。
对我来说,一个反复出现的问题是,例如,是否要编写像这样的类似缩小函数
template <typename Container, typename Element>
E reduce_something(const Container<Element> & a)
{
// ...
}
或跳过像这样的元素类型
template <typename Container>
Container::element_type reduce_something(const Container & a)
{
// ...
}
以及何时使用嵌套模板。
答案 0 :(得分:2)
我通常会尽量确保对模板类型施加尽可能少的要求和限制,因为我可以合理地将其作为指导原则。
template <typename Container, typename Element>
E reduce_something(const Container<Element> & a)
{
// ...
}
这是不正确的,它需要像:
template < template<typename> class Container, typename Element>
Element reduce_something(const Container<Element> & a)
{
// ...
}
但这增加了Container
的许多要求。它只需要一个模板参数,因此像std::vector
这样的东西不会,因为它有一个allocator模板参数。我可以用非模板类型Container
编写一个模板函数,而不假设它是一个模板类型,如果我想要与Element
交互的操作在模板实例化时执行,那么一切都会无论如何工作。
template <typename Container>
Container::element_type reduce_something(const Container & a)
{
// ...
}
这增加了Container
必须包含element_type
类型成员的关键要求。最好使用traits类,以便为标准容器(代之为value_type
)和其他无法直接修改的类型创建特征。
可能更好的方法是采用迭代器分隔的范围。 E.g。
#include <iterator>
template<InputIterator>
typename std::iterator_traits<InputIterator>::value_type
reduce_something(InputIterator first, InputIterator last)
{
// ...
}
已经有一个合适的标准traits类,该算法将使用子范围,由指针和所有容器分隔的范围。
答案 1 :(得分:1)
您是否考虑过传入和返回一个或多个迭代器类型的规范C ++方法?在这种情况下,传入一个开始和结束来指定范围,并使用相同的类型或不同的迭代器类型作为返回值。