如何重载模板函数以匹配特定容器
How to overload a template function to match specific containers?
我有以下函数来检索容器的n
元素 - O(n)
:
template<typename Container>
const typename Container::value_type& getNthElement(const Container& container, size_t n) {
auto itr = cbegin(container);
for (auto i = 0u; i < n; ++i) {
++itr;
}
return *itr;
}
对于vectors
我有这种过载 - O(1)
:
template<typename T>
T getNthElement(const vector<T>& container, size_t n) {
return container[n];
}
现在,如果我想使用 deque(它也具有O(1)
实现),第一个模板函数将使用O(n)
实现调用。
如何使第二个过载功能适应vectors
和deques
的工作?
我的问题取自这篇文章。
简单的方法是基于迭代器类别进行标记,即如下所示:
template <typename It>
typename std::iterator_traits<It>::value_type
nth_element(It begin, It end, std::size_t n, std::input_iterator_tag) {
for (std::size_t i(0); it != end && i != n; ++i) {
++i;
}
return it != end? *it: throw std::runtime_error("out of range");
}
template <typename It>
typename std::iterator_traits<It>::value_type
nth_element(It begin, It end, std::size_t n, std::random_access_iterator_tag) {
return n < std::size_t(end - begin)? it[n]: std::runtime_error("out of range");
}
template <typename C>
typename C::value_type
nth_element(Container const& c, std::size_t n) {
return nth_element(c.begin(), c.end(), n,
typename std::iterator_traits<C>::iterator_category());
}
如果不是因为n
可能太大,你实际上可以让std::advance()
做到这一点:
template <typename C>
typename C::value_type
nth_element(Container const& c, std::size_t n) {
auto it = c.begin();
std::advance(it, n);
return *it;
}
借助 C++11 扩展的 SFINAE,您可以嗅出即使没有性状,此功能是否可用。
相关文章:
- 继承函数的重载解析
- 函数何时会在c++中包含stack_Unwind_Resume调用
- 嵌套模板函数的重载
- 基于 SFINAE 的特征实现问题与函数模板重载
- 如果我也使用复制构造函数并且重载 = 运算符,我是否需要析构函数?
- C++在赋值或回调函数时重载模板
- 使用继承的指针列表复制构造函数或重载运算符=
- 将显式指定的函数模板重载作为模板参数传递的正确语法是什么?
- 复制构造函数和重载加法运算符
- 模板函数的重载解析
- 具有非模板类型参数的模板函数的重载解析
- 错误消息:使用复制构造函数和重载赋值运算符
- boost::enable_if on 成员函数,重载返回类型
- 函数模板重载 - 部分专用化
- 不同类的构造函数的重载解析
- 调用非静态函数的重载括号运算符
- 非类型模板参数中的占位符类型是否涉及作为模板参数传递的函数的重载解析?
- 如何将同名的继承函数视为重载函数
- 跨编译器的 constexpr 成员函数的重载解析不一致
- 为什么为单个赋值操作调用复制构造函数和重载赋值运算符