我可以重载插入运算符以获取模板化STL容器吗?

Ita*_*iwa 10 c++

我有一个关于STL容器的示例,所以我正在阅读它们,对我而言,重复使用range-for循环来打印容器的内容非常乏味。所以我想关于重载插入运算符<<因此我可以这样写:std::cout << container << std::endl;

template<class T>
std::ostream& operator<<(std::ostream& out, const std::list<T>& v) {
    for (const auto& e : v)
        out << e << ", ";
    return out;
}

int main() {

    std::list<int> vi{ 10, 24, 81, 57, 2019 };

    vi.pop_back();
    std::cout << vi << std::endl; // 10, 24, 81, 57,

    std::deque<std::string> names{ "Hello", "STL Containers" };
    std::cout << names << std::endl; // error here. Bacause I've not overloaded << to take a std::deque<T>


}
Run Code Online (Sandbox Code Playgroud)

如您在上面看到的,我发现打印list某种类型的纸很舒服。问题是我只能打印列表,而不能打印其他种类的容器,例如a vectordeque...

那么,如何超载<<以获取类型T<U>的容器?还是应该专门针对所有容器?在一个真实的例子中,我不应该这样做吗?

Viv*_*ick 1

您可以提供以下重载:

template <class...>
using void_t = void;

template <class... Args>
constexpr bool exists_t_v(){
  return std::is_same<void_t<Args...>, void>::value;
}


template <class Container, class = std::enable_if<
  exists_t_v<
    decltype(std::begin(std::declval<Container>())),
    decltype(std::end(std::declval<Container>()))
  >()
>>
std::ostream& operator<<(std::ostream& os, Container&& container){
  for(const auto& e : std::forward<Container>(container))
    os << e << ',';

  return os;
}
Run Code Online (Sandbox Code Playgroud)

这将允许定义和的container类型的任何实例使用重载。Containerstd::begin(container)std::begin(container)

此类解决方案的问题之一是std::string支持以及已经为其定义了自己的重载的任何std::begin()类型std::end()