ostream运算符<<重载了STL容器,并通过std :: string中断了它?

时间:2018-09-19 16:22:11

标签: c++ string templates stl operator-overloading

因此,我重载了ostream <<运算符,以便它可以使用大多数STL容器并进行打印。但是,它不适用于传递字符串(错误是“ cout << s;”行的“歧义过载”)。如何使它在字符串上好像没有重载一样起作用?

#include <bits/stdc++.h>
using namespace std;

template<typename T>
ostream& _containerprint(ostream &out, T const &val) {
  return (out << val << " ");
}

template<typename T1, typename T2>
ostream& _containerprint(ostream &out, pair<T1, T2> const &val) {
  return (out << "{" << val.first << " " << val.second << "} ");
}

template<template<typename, typename...> class TT, typename... Args>
ostream& operator<<(ostream &out, TT<Args...> const &cont) {
  for(auto&& elem : cont) {
    _containerprint(out, elem);
  }
  return out;
}

int main() {
  string s = "help me";
  cout << s;
}

编辑:请不要害怕,#include <bits/stdc++.h>是因为它是用于编程比赛的设置;真的没关系!

2 个答案:

答案 0 :(得分:4)

std::string是模板类(std::basic_string<char>的别名)

因此std::cout << s与您的过载匹配,而std::basic_string<T>与您的过载匹配。

没有一个过载比另一个过载更专业。

可能的解决方法是为std::string添加额外的重载:

std::ostream& operator << (std::ostream& out, const std::string& s)
{
    return operator << <char>(out, s);
    // Select template <class CharT, class Traits, class Allocator>
    // std::basic_ostream<CharT, Traits>& 
    // operator<<(std::basic_ostream<CharT, Traits>& os,
    //            const std::basic_string<CharT, Traits, Allocator>& str);
}

Demo

答案 1 :(得分:0)

使您的ostream参数更通用,从而使您的重载比std::string的标准参数更通用。

template<typename CharT, typename Traits, typename T>
ostream& _containerprint(std::basic_ostream<CharT, Traits> &out, T const &val) {
  return (out << val << " ");
}

template<typename CharT, typename Traits, typename T1, typename T2>
ostream& _containerprint(std::basic_ostream<CharT, Traits> &out, pair<T1, T2> const &val) {
  return (out << "{" << val.first << " " << val.second << "} ");
}

template<typename CharT, typename Traits, template<typename, typename...> class TT, typename... Args>
ostream& operator<<(std::basic_ostream<CharT, Traits> &out, TT<Args...> const &cont) {
  for(auto&& elem : cont) {
    _containerprint(out, elem);
  }
  return out;
}