c++11 - msvc++ doesn't see overloaded operator<< -


i'm porting piece of code written linux , compiled gcc v4.8.2 (using -std=c++11) windows. part of overloaded operator<< msvc++ 2013 doesn't agree with. condensed example below.

we've defined custom stream class supports standard stream manipulator functions. reason we've overloaded operator<< accepts function pointer second argument.

if define templated overload of operator<< . msvc++ complains:

error c2676: binary '<<' : 'foobar' not define operator or conversion type acceptable predefined operator

but if specify type of second argument std::ostream instead of templated std::basis_ostream<..,..> code works expected.

at first thought had messed template arguments. however, if define arbitrary template function instead of overload of operator<< code compiles fine. what's going on here?

example

#include "stdafx.h"  #include <iostream> #include <sstream> #include <string>  struct foobar {     std::stringstream s_; };  /* causes compiler error c2676 template <typename chart = char, typename traits = std::char_traits<chart> > foobar& operator<<(foobar& foo, std::basic_ostream<chart, traits>& (*manip)(std::basic_ostream<chart, traits>&)) {     foo.s_ << manip;     return foo; }  */  /* works intendend */ foobar& operator<<(foobar& foo, std::ostream& (*manip)(std::ostream&)) {     foo.s_ << manip;     return foo; }  /* works */ template <typename chart = char, typename traits = std::char_traits<chart> > foobar& qux(foobar& foo, std::basic_ostream<chart, traits>& (*manip)(std::basic_ostream<chart, traits>&)) {     foo.s_ << manip;     return foo; }  int _tmain(int argc, _tchar* argv[]) {     foobar foo;     foo << std::endl;      qux(foo, std::endl);     return 0; } 

there appears kind of bug default arguments, overloaded operators, , template function parameter overload resolution.

these complex, sort of understandable.

the news shouldn't taking just any iomanip there -- should taking specific one.

you can either hard code it, or deduce so:

// nth type template instance: template<class...>struct types{using type=types;}; template<class t, size_t n> struct nth{}; template<class t, size_t n> using nth_t=typename nth<t,n>::type; template<template<class...>class z, class t0, class...ts, size_t n> struct nth<z<t0,ts...>,n>:nth<types<ts...>,n-1>{}; template<template<class...>class z, class t0, class...ts> struct nth<z<t0,ts...>,0>{using type=t0;};  // string type, produce compatible basic_stream type: template<class string> using compat_stream = std::basic_ostream<nth_t<string,0>, nth_t<string,1>>;  // type t, produce signature of function pointer // pass-through manipulates it: template<class t> using manip_f = t&(*)(t&);  // string type, produce compatible io-manipulator: template<class string> using io_manip_f = manip_f< compat_stream<string> >;  // return of foobar: struct foobar {   std::stringstream s_;   // type of manipulators compatible s_:   using manip_f = io_manip_f<std::stringstream> manip;   // koenig operator<<:   friend foobar& operator<<( foobar& self, manip_f manip ) {     self.s_ << manip;     return self;   } }; 

Comments

Popular posts from this blog

Java 3D LWJGL collision -

spring - SubProtocolWebSocketHandler - No handlers -

methods - python can't use function in submodule -