如何打印通用std :: list迭代器?

问题描述

我希望能够通过打印其值来打印任何std::list迭代器。我的初始代码如下:

template<typename T>
std::ostream& operator<<(std::ostream& os,const typename std::list<T>::const_iterator& x)
{
   return os << "&" << *x;
}

这没有用,因为编译器无法确定参数T。然后,我尝试使其对迭代器类型本身具有通用性,并使用iterator_traits将其限制为迭代器。

template<
    typename It,typename = typename std::iterator_traits<It>::value_type
>
std::ostream &operator<<(std::ostream &os,const It &x)
{
    return os << "&" << *x;
}

但是,当然,我得到了std::ostream << *const char的两个冲突的实现,因为指针也是迭代器。 如何将实现限制为std::list个迭代器,以免发生冲突?

解决方法

您可以将类型限制为iterator的{​​{1}}或const_iterator。例如

std::list
,

您可以SFINAE const char*摆脱operator<<超载。

#include <type_traits> // std::enable_if_t,std::is_same_v,std::remove_reference_t

template<
    typename It,typename = typename std::iterator_traits<It>::value_type
>
auto operator<<(std::ostream &os,const It &x)
-> std::enable_if_t< !std::is_same_v<std::remove_reference_t<It>,const char*>,std::ostream&>
{
    return os << "&" << *x;
}

See a Demo

请注意,以上内容不仅限于std::list::iterator ,这意味着来自其他容器的迭代器也可以考虑此重载。这可能不是您想要的行为。


自从我们could not get the container type from the iterator以来,我建议与注释中提到的 @super 相同。 为 Legacy Bidirectional Iterator 提供operator<<重载 std::list就是这样。

以下是示例代码,该代码适用于您期望的情况以及满足以下条件的所有容器: 双向迭代器的要求。

#include <list>
#include <iostream>
#include <iterator>    // std::iterator_traits,std::bidirectional_iterator_tag
#include <type_traits> // std::is_same_v,std::enable_if_t

// SFINAE helper  type for bidirectional_iterator_t
template<typename Iterator,typename ReType = void>
using enable_for_bidirectional_iterator_t
= std::enable_if_t<
   std::is_same_v<std::bidirectional_iterator_tag,typename std::iterator_traits<Iterator>::iterator_category>,ReType
>;

template<typename Iterator>
auto operator<<(std::ostream& os,const Iterator x) noexcept
-> enable_for_bidirectional_iterator_t<Iterator,std::ostream&>
{
   return os << "&" << *x;
}

See a Demo


但是,通常,您为容器而不是迭代器提供operator<<重载。您可能需要重新考虑设计。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...