C++11 msvc&x2B+;不';看不到重载运算符<&书信电报;

C++11 msvc&x2B+;不';看不到重载运算符<&书信电报;,c++11,visual-c++,C++11,Visual C++,我正在将一段为Linux编写并使用gcc v4.8.2(使用-std=c++11)编译的代码移植到Windows。它的一部分是一个重载的操作符似乎有一些带有默认参数、重载操作符和模板函数参数重载解析的bug 这些都很复杂,可以理解 好消息是,你不应该只服用任何一种iomanip,你应该服用一种特定的iomanip 您可以硬编码,也可以这样推断: // Get the nth type from a template instance: template<class...>struct

我正在将一段为Linux编写并使用gcc v4.8.2(使用-std=c++11)编译的代码移植到Windows。它的一部分是一个重载的
操作符似乎有一些带有默认参数、重载操作符和模板函数参数重载解析的bug

这些都很复杂,可以理解

好消息是,你不应该只服用任何一种iomanip,你应该服用一种特定的iomanip

您可以硬编码,也可以这样推断:

// Get the nth type from a 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;};

// From a String type, produce a compatible basic_stream type:
template<class String>
using compat_stream = std::basic_ostream<nth_t<String,0>, nth_t<String,1>>;

// From a type T, produce a signature of a function pointer that
// pass-through manipulates it:
template<class T>
using manip_f = T&(*)(T&);

// From a String type, produce a compatible io-manipulator:
template<class String>
using io_manip_f = manip_f< compat_stream<String> >;

// The return of foobar:
struct foobar {
  std::stringstream s_;
  // the type of manipulators that is compatible with s_:
  using manip_f = io_manip_f<std::stringstream> manip;
  // a Koenig operator<<:
  friend foobar& operator<<( foobar& self, manip_f manip ) {
    self.s_ << manip;
    return self;
  }
};
//从模板实例获取第n个类型:
templatestruct类型{using type=types;};
模板
结构n{};
模板
使用n_t=typename n::type;
模板
结构n:n{};
模板
结构n{using type=T0;};
//从字符串类型生成兼容的基本\u流类型:
模板
使用compat_stream=std::basic_ostream;
//从类型T生成函数指针的签名,该函数指针
//“通过”操作它:
模板
使用manip_f=T&(*)(T&);
//从字符串类型生成兼容的io操纵器:
模板
使用io_manip_f=manip_f;
//foobar的回归:
结构foobar{
std::stringstreams_u2;;
//与s_兼容的操纵器类型:
使用manip_f=io_manip_f manip;

//Koenig运算符看起来像编译器bug。g++5.1和clang++3.6都接受该程序,以及vc++19(参见示例)
std::endl
不是一个函数,它是一个模板函数。你把它传递给一个特定的签名,它就会找到重载。你把一个带有类型模板的函数传递给它,它就会出错?但只有在你进行运算符重载时才会出错。请注意,
CharT
Traits
永远无法推导出来(因为
std::endl
是一个函数模板),因此您也可以直接使用第二个版本的
操作符,
@yakhow?和
decltype(foobar::s)
?将
stringstream
用作“字符串类型”会有点混淆。@dyp甚至
ostream
也可以作为“字符串类型”根据上面的定义。是的,这很奇怪:我想从中提取“字符串类型信息”,即字符类型和特征。
// Get the nth type from a 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;};

// From a String type, produce a compatible basic_stream type:
template<class String>
using compat_stream = std::basic_ostream<nth_t<String,0>, nth_t<String,1>>;

// From a type T, produce a signature of a function pointer that
// pass-through manipulates it:
template<class T>
using manip_f = T&(*)(T&);

// From a String type, produce a compatible io-manipulator:
template<class String>
using io_manip_f = manip_f< compat_stream<String> >;

// The return of foobar:
struct foobar {
  std::stringstream s_;
  // the type of manipulators that is compatible with s_:
  using manip_f = io_manip_f<std::stringstream> manip;
  // a Koenig operator<<:
  friend foobar& operator<<( foobar& self, manip_f manip ) {
    self.s_ << manip;
    return self;
  }
};