gpt4 book ai didi

c++ - 输出迭代器的 value_type

转载 作者:IT老高 更新时间:2023-10-28 21:42:58 27 4
gpt4 key购买 nike

STL 通常这样定义输出迭代器:

template<class Cont>
class insert_iterator
: public iterator<output_iterator_tag,void,void,void,void> {
// ...

为什么输出迭代器要定义 value_type作为 void ? 算法知道它应该输出什么类型的值会很有用。

例如,翻译 URL 查询的函数 "key1=value1&key2=value2&key3=value3"放入任何包含键值字符串元素的容器中。

template<typename Ch,typename Tr,typename Out>
void parse(const std::basic_string<Ch,Tr>& str, Out result)
{
std::basic_string<Ch,Tr> key, value;
// loop over str, parse into p ...
*result = typename iterator_traits<Out>::value_type(key, value);
}

SGI reference page of value_type 提示这是因为不可能取消引用输出迭代器。但这不是 value_type 的唯一用途。 :我可能想实例化一个以便将其分配给迭代器。

有什么替代方法可以使用输出迭代器构造要输出的值?我考虑了两种方法:

  • 接受一个能返回正确类型对象的仿函数参数。我仍然想要一个不采用该函数对象参数的算法版本。
  • 要求输出容器保存 pair<string,string> , 或者可以从中转换的类型。我想知道我是否可以没有这个要求,也许允许任何可以从两个 std::string 构造的元素s.

最佳答案

迭代器的真正值类型很可能是迭代器本身。 operator*可能很容易返回对 *this 的引用因为真正的工作是由赋值运算符完成的。您可能会发现 *it = x;it = x;与输出迭代器具有完全相同的效果(我想可能会采取特殊措施来防止后者编译)。

因此,定义真正的值类型同样没用。将其定义为 void ,另一方面,可以防止以下错误:

 typename Iter::value_type v = *it; //useless with an output iterator if it compiled

我想这只是输出迭代器概念的限制:它们是“滥用”运算符重载的对象,以便出现指针状,而实际上正在发生完全不同的事情。

不过,您的问题很有趣。如果你想支持任何容器,那么有问题的输出迭代器可能是 std::insert_iterator , std::front_insert_iteratorstd::back_insert_iterator .在这种情况下,您可以执行以下操作:

#include <iterator>
#include <vector>
#include <string>
#include <map>
#include <iostream>

//Iterator has value_type, use it
template <class T, class IterValue>
struct value_type
{
typedef IterValue type;
};

//output iterator, use the container's value_type
template <class Container>
struct value_type<Container, void>
{
typedef typename Container::value_type type;
};

template <class T, class Out>
void parse_aux(Out out)
{
*out = typename value_type<T, typename Out::value_type>::type("a", "b");
}

template <template <class> class Out, class T>
void parse(Out<T> out)
{
parse_aux<T>(out);
}

//variadic template in C++0x could take care of this and other overloads that might be needed
template <template <class, class> class Out, class T, class U>
void parse(Out<T, U> out)
{
parse_aux<T>(out);
}

int main()
{
std::vector<std::pair<std::string, std::string> > vec;
parse(std::back_inserter(vec));
std::cout << vec[0].first << ' ' << vec[0].second << '\n';

std::map<std::string, std::string> map;
parse(std::inserter(map, map.end()));
std::cout << map["a"] << '\n';

//just might also support normal iterators
std::vector<std::pair<std::string, std::string> > vec2(1);
parse(vec2.begin());
std::cout << vec2[0].first << ' ' << vec2[0].second << '\n';
}

它仍然只能让你走到这一步。我想人们可以更进一步,所以它也可以管理,比如说,std::ostream_iterator<printable_type> ,但在某些时候它会变得如此复杂,以至于如果出现问题,需要上帝来破译错误消息。

关于c++ - 输出迭代器的 value_type,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2619551/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com