迭代器的真正值类型很可能是迭代器本身。
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_iterator
和
std::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>
但在某个时刻,它会变得如此复杂,以至于如果出了问题,上帝需要破译错误信息。