C++类字符串类型的迭代器
C++ iterator to string-like types
计划是实现一个具有两个构造函数的类。第一个 ctor 应该采用类似字符串的类型,第二个 ctor 应该采用两个迭代器(开始和结束(到字符串类对象的容器。在内部,该类将使用const char*
、以 null 结尾的 C 字符串。对于第一个 ctor,这是一项简单的任务,我可以明确表示。传入具有str.c_str()
或类似字符串类型的C++string
可以正常工作。但是,对于第二个 ctor,我不太确定应该如何实现它。通常,它应该是具有可转换为const char*
的值类型的LegcayInputIterator
。从我的头顶上,我可以想到至少 4 种我想要支持的类型,而让第二个 ctor 超载这么多似乎是错误的方法。
为什么我的第二个 ctor 编译失败?应定义++
、!=
和*
运算符。将两个迭代器传递给T
但实际上允许我可以从中获取const char*
的不同字符串类类型(请参阅代码中的示例 5(的工作方法是什么?
示例代码应该说明我的方法,但不幸的是不起作用。
#include <vector>
#include <array>
#include <cstdio>
#include <string>
#include <iterator>
struct Example {
using CtorIterator = std::iterator<std::input_iterator_tag, const char*>;
Example(const char *text)
{
std::printf("Called single argument ctor, text = %sn", text);
}
Example(CtorIterator begin, CtorIterator end)
{
std::printf("Called iterator ctor, text = [");
for (auto it = begin; it != end; ++it)
std::printf("%s, ", *it);
std::printf("]n");
}
};
int main(int argc, char **argv) {
Example ex1("Hello");
std::string arg2("String");
Example ex2(arg2.c_str());
std::vector<const char*> args3{"A", "B", "C"};
std::array<const char*, 3> args4{"D", "E", "F"};
std::vector<std::string> args5{"G", "H", "I"};
Example ex3(args3.begin(), args3.end());
Example ex4(args4.begin(), args4.end());
Example ex5(args5.begin(), args5.end()); // won't work
return 0;
}
std::iterator
不应该这样使用。它被引入到库中,通过提供某些成员类型(如iterator_category
和value_type
(来支持用户定义的迭代器。std::iterator
是一个空类,按价值获取它是没有意义的。通过引用获取它也没有多大意义,因为迭代器不必从中派生。std::iterator
自 C++17 日起已弃用。
LegcayInputIterator
不是一个类,而是一个类型应该满足的要求的集合。类型本身不是固定的,应该是模板参数。从 C++20 开始,当概念成为语言功能时,您将能够编写如下内容:
template<typename InputIt> requires InputIterator<InputIt>
Example(It begin, It end) { ... }
或
template<InputIterator InputIt>
Example(It begin, It end) { ... }
检查InputIt
是否确实满足输入迭代器的要求。这里InputIterator
是一个概念,有关特定示例,请参阅此处。在那之前,您只需写:
template<typename InputIt>
Example(InputIt begin, InputIt end) { ... }
例如,std::vector
的构造函数来自范围[first, last)
是这样声明的:
template<class InputIt>
vector(InputIt first, InputIt last, const Allocator& alloc = Allocator());
惯用的方法是改用模板:
template<typename IterT>
Example(IterT begin, IterT end) { ... }
你使用std::iterator<...>
的方式不起作用,因为很少有容器迭代器实际上是std::iterator<...>
类型,并且没有转换运算符。
它并没有真正解决为什么它不起作用的问题,但你可以利用std::begin
和std::end
struct Example {
Example(const char *text)
{
std::printf("Called single argument ctor, text = %sn", text);
}
template<typename T>
Example(const T &t)
{
std::printf("Called iterator ctor, text = [");
for (auto it = std::begin(t); it != std::end(t); ++it)
std::printf("%s, ", *it);
std::printf("]n");
}
};
用于完全在范围底座上的继电器,用于:
struct Example {
Example(const char *text)
{
std::printf("Called single argument ctor, text = %sn", text);
}
template<typename T>
Example(const T &t)
{
std::printf("Called iterator ctor, text = [");
for (const auto &c : t)
std::printf("%s, ", c);
std::printf("]n");
}
};
- 如何在c++迭代器类型中包装std::chrono
- 定义模板参数的迭代器类型
- C++如何乘以包含 std::variant 元素的向量的迭代器?正在执行迭代器类型的转换?
- C++不兼容的迭代器类型
- 如何推导 std::高级迭代器类型?
- 在 stl 容器包装器中定义迭代器类型
- 矢量迭代器类型未知
- STD ::向量迭代器类型和允许的操作
- 检查容器模板类中的迭代器类型
- 如何断言模板参数的类型 STL 迭代器类型
- 检测容器是否具有迭代器类型
- 由set2.begin()返回的迭代器类型
- 序列容器的迭代器类型是什么?
- 如何推断嵌套最多的迭代器类型
- 为什么迭代器类型与矢量容器中的 value_type * 不匹配
- ISO C++禁止声明没有自动迭代器类型的“it”
- 使用的迭代器类型错误
- 列表的迭代器类型
- 如何打印迭代器类型列表<pair<int,int>>::iterator itrator it指向的元素
- 为什么 void* 不是迭代器类型?