尝试继承std::ostream
并使用自定义operator <<
时遇到了一些麻烦,该自定义std::ostream <<
基本上是在做一些工作,然后转发到#include <iostream>
#include <ostream>
struct ostream : std::ostream{
using std::ostream::ostream;
template<typename T>
ostream &operator <<(T &&arg){
//some work...
static_cast<std::ostream&>(*this) << std::forward<T>(arg);
return *this;
}
};
int main(){
ostream cc(std::cout.rdbuf());
cc << "hello world";
//cc << "hello world" << std::endl; //couldn't deduce template parameter `T`
}
,例如:
std::ostream::operator <<
问题是使用操纵器时,就像我注释掉的那一行一样,gcc抱怨[模板参数推导/替换失败:]。
我是否必须显式设置模板类型?如果可以,如何设置?,因为由于不完整而无法使用in类operator <<
。
编辑
我刚刚将自定义ostream
定义为自由函数,因此没有在类#include <iostream>
#include <ostream>
struct ostream : std::ostream{
using std::ostream::ostream;
};
template<typename T>
ostream &operator <<(ostream &os, T &&arg)
{
static_cast<std::ostream&>(os) << std::forward<T>(arg);
return os;
}
int main(){
ostream cc(std::cout.rdbuf());
cc << "hello world" << std::endl;
}
内
{{1}}
,它对于机械手也按预期工作。不知道为什么这会有所作为,也许有人可以帮我澄清一下
答案 0 :(得分:2)
问题是操纵器是模板化的,并且您的类没有提供为std::endl
选择正确的模板参数所需的信息。您应该为操纵器重载operator<<
:
struct ostream : std::ostream{
using std::ostream::ostream;
template<typename T>
ostream &operator <<(T &&arg){
//some work...
static_cast<std::ostream&>(*this) << std::forward<T>(arg);
return *this;
}
ostream &operator<<(
std::ostream &(*manip)(std::ostream&)) {
//some work...
static_cast<std::ostream&>(*this) <<manip;
return *this;
}
};
请注意,问题中的代码由于以下原因而失败:
auto manip = std::endl;
它根本无法推论endl
的模板参数。
更新
使ovloading成为自由函数的替代方法并没有实现人们的期望:
template<typename T>
ostream &operator <<(ostream &os, T &&arg)
{
static_cast<std::ostream&>(os) << std::forward<T>(arg);
return os;
}
int main(){
ostream cc(std::cout.rdbuf());
cc << "hello world" << std::endl;
}
获取std::endl
的运算符来自原始的iostream库。在这种情况下,编译器不会执行重载函数,因此没有编译错误。
如果您不想使操纵器过载,则可以显式提供模板参数:
cc << "hello world" << std::endl<char, std::char_traits<char>>;