STL容器迭代器的模板特化
Template specialization for iterators of STL containers?
我正在尝试编写一个类似于std::to_string
的模板函数,适用于基本类型以及STL容器的迭代器。但是我不确定如何编写足够具体的模板来识别迭代器。
到目前为止我所尝试的是尝试在STL容器中使用iterator
类型定义
template<typename... Args, template <typename...> class Container>
static string to_string(typename Container<Args...>::iterator s) { ...
下面是一个最小的例子。代码编译后,模板函数My::to_string
无法匹配上述签名,将std::set<int>::iterator
作为默认类型处理。
我的问题是如何以一种通用的方式正确地编写它,以便模板函数My::to_string
可以拾取迭代器,但不会将迭代器与其他标准模板类型(如std::string
)混淆。
提前感谢。
#include <set>
#include <iostream>
using namespace std;
class My{
//base case
template<typename T>
static string to_string(const T& t) {
return "basic ";
}
//specialization for string
template <typename Char, typename Traits, typename Alloc>
static string to_string(const std::basic_string<Char, Traits, Alloc>& s) {
return (string)s;
}
//Problem line: how to write specialization for iterators of standard containers?
template<typename... Args, template <typename...> class Container>
static string to_string(typename Container<Args...>::iterator s) {
return "itor ";
}
};
int main() {
int i = 2;
string str = "Hello";
set<int> s;
s.insert(i);
cout << to_string(i) << ", " << str << ", "
<< to_string(s.begin()) << endl; //didn't get captured by iterator spec.
}
输出:basic, Hello, basic
所需输出:basic, Hello, itor
如果您只关心参数的迭代器性,而不关心容器的类型,那么您可以SFINAE出另一个重载。
首先生成一个is_iterator
性状,如下图所示:
template <typename T>
struct sfinae_true : std::true_type {};
struct is_iterator_tester {
template <typename T>
static sfinae_true<typename std::iterator_traits<T>::iterator_category> test(int);
template <typename>
static std::false_type test(...);
};
template <typename T>
struct is_iterator : decltype(is_iterator_tester::test<T>(0)) {};
现在SFINAE出错误的重载取决于类型是否是迭代器:
//base case
template<typename T>
static std::enable_if_t<!is_iterator<T>::value, string> to_string(const T& t) {
return "basic ";
}
//specialization for string
template <typename Char, typename Traits, typename Alloc>
static string to_string(const std::basic_string<Char, Traits, Alloc>& s) {
return (string)s;
}
//Problem line: how to write specialization for iterators of standard containers?
template<typename T>
static std::enable_if_t<is_iterator<T>::value, string> to_string(const T& s) {
return "itor ";
}
演示。
如果您将特定于迭代器的重载约束为与定义了operator*
的任何类型一起工作(Live at Coliru),则这非常简单:
namespace My {
// base case
using std::to_string;
// overload for strings
template <typename Char, typename Traits, typename Alloc>
std::basic_string<Char, Traits, Alloc>
to_string(std::basic_string<Char, Traits, Alloc> s) {
return s;
}
// overload for iterators
template<typename Iterator>
auto to_string(Iterator i) -> decltype(to_string(*i)) {
return "iterator to: "" + to_string(*i) + '"';
}
}
应该是这样的:
template<typename ForwardIterator>
static string to_string(ForwardIterator begin, ForwardIterator end) {
return "itor ";
}
相关文章:
- 自定义 STL 兼容迭代器,用于迭代 2D 数组类的列
- "迭代器"和"const_iterator"不是 STL 容器的必需成员?
- 没有 STL 容器的迭代器
- 为什么某些 STL 容器(堆栈、队列、优先级队列)不支持迭代器?
- 迭代器 STL C++是模板、类还是接口?
- 为什么我们不在 STL 的迭代器中传递星号(*)
- 成员函数不能为集合迭代器和const_iterator的输入重载(但可以为其他 STL 迭代器重载)
- 如何在C++中重新实现包含指针的 STL 容器的类的迭代器
- C++如何获取传递给函数(STL 迭代器)的参数的名称
- 迭代器和 STL 容器的关系
- C++ 中 STL 中迭代器的大小(以字节为单位)是多少
- 如何将 stl 迭代器与特征一起使用?
- 用于 STL 迭代器、指针和 std::nullptr_t 的模板函数
- 在 stl 容器包装器中定义迭代器类型
- 在多个 STL 对对象上创建迭代器
- 如何为获取 stl 容器迭代器的函数提供函数签名?
- 在 stl 算法中移动迭代器
- lower_bound 在 C++ STL 中返回迭代器,即使元素不存在也是如此.如何避免这种情况?
- 并行STL插入迭代器,例如std :: back_insert_iterator
- STL 迭代器继承:"value_type"不命名类型