Best way to specialise operator<< for std::ostream and std::vector with generic template functions?

前端 未结 2 1666
广开言路
广开言路 2021-01-03 03:35

I am having trouble with the two-phase look-up as specified by the standard and (correctly) implemented by clang in connection with an overload of operator<<

2条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2021-01-03 04:16

    I followed Jonathan’s advice and used a wrapper Printable<> to define the operator<<. By making this wrapper also implicitly-convertible to the original type, I can handle both cases where only Printable is printable as well as those were also T itself was printable. Code as follows:

    template
    struct Printable {
      T const& ref;
      Printable(T const& ref) : ref(ref) { }
      operator T const& () { return ref; }
    };
    
    template
    Printable printable(T const& in) { return Printable(in); }
    
    template
    void shift(Stream& s, Arg& arg) {
      s << printable(arg);
    }
    
    #include 
    #include 
    std::ostream& operator<<(std::ostream& out, Printable > const& v) {
      for(auto const& elem : v.ref) { s << elem << ", "; }
      return s;
    }
    
    struct MyClass { };
    std::ostream& operator<<(std::ostream& s, MyClass const& m) {
      return s << "MyClass\n";
    }
    
    int main() {
      std::vector v{1,2,3};
      MyClass m;
    
      shift(std::cout, v);
      shift(std::cout, m);
    }
    

    This has the advantage that at the point of use in the call to shift(), I don’t have to care what sort of type my variable has. Only in the definition of operator<< for classes I have to be careful as well as when using such an operator.

提交回复
热议问题