KCH*_*KCH 4 c++ templates operators visual-studio-2010
我正在尝试使C++类类似 std::ostream
,它将输入并写入std::ostream
构造函数中给出的两个s.这里它与适当的operator<<
模板一起:
struct SplitStream
{
SplitStream(std::ostream & a_, std::ostream & b_) : a(a_), b(b_) {}
std::ostream & a, & b;
};
template<class T>
const SplitStream & operator << (const SplitStream & sp, const T & x)
{
sp.a << x;
sp.b << x;
return sp;
}
Run Code Online (Sandbox Code Playgroud)
这段代码下面有几行,我尝试使用这个类:
void foo(SplitStream & out)
{
double some_double = 1.23;
out << "bar" << some_double << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
我得到了这个相当神秘的错误:
... error C2678: binary '<<' : no operator found which takes a left-hand operand of type 'const SplitStream' (or there is no acceptable conversion) ...
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?我试图定义operator<<
没有consts,它也没有编译.
当前的问题是,std::endl
它不是一个对象,而是一个声明如下的函数模板:
template <typename cT, typename Traits>
std::basic_ostream<cT, Traits>& endl(std::basic_ostream<cT, Traits>&);
Run Code Online (Sandbox Code Playgroud)
要使用这样的函数指针,需要推导出模板参数.为此,该类std::basic_ostream<cT, Traits>
声明了适合的重载operator<<()
:
template <typename cT, typename Traits>
std::basic_ostream<cT, Traits>& std::baisic_ostream<cT, Traits>::operator<< (
std::basic_ostream<cT, Traits>& (*manip)(std::basic_ostream<cT, Traits>&));
Run Code Online (Sandbox Code Playgroud)
这样,编译器可以在std::endl
引用函数时推导出正确的实例化.
然而,所有这一切都完全无关紧要,因为你要做的事情完全不同!您应该创建一个合适的流缓冲区,并使用合理构造的std::ostream
自定义流缓冲区.下面是一个完整的例子,如何正确地做到这一点(我以前发过它但只有几十次......):
#include <streambuf>
struct teebuf
: std::streambuf
{
std::streambuf* sb1_;
std::streambuf* sb2_;
teebuf(std::streambuf* sb1, std::streambuf* sb2)
: sb1_(sb1), sb2_(sb2) {
}
int overflow(int c) {
typedef std::streambuf::traits_type traits;
bool rc(true);
if (!traits::eq_int_type(traits::eof(), c)) {
traits::eq_int_type(this->sb1_->sputc(c), traits::eof())
&& (rc = false);
traits::eq_int_type(this->sb2_->sputc(c), traits::eof())
&& (rc = false);
}
return rc? traits::not_eof(c): traits::eof();
}
int sync() {
bool rc(true);
this->sb1_->pubsync() != -1 || (rc = false);
this->sb2_->pubsync() != -1 || (rc = false);
return rc? 0: -1;
}
};
#include <fstream>
#include <iostream>
int main()
{
std::ofstream fout("tee.txt");
teebuf sbuf(fout.rdbuf(), std::cout.rdbuf());
std::ostream out(&sbuf);
out << "hello, world!\n";
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
151 次 |
最近记录: |