问题描述
我试图让一个类似于 c >:
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>&))
这样,编译器可以推导出 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 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!\\\
;
}
I'm trying to make a C++ class resembling std::ostream, that will take its input and write to two std::ostreams given in the constructor. Here it is together with appropriate operator<< template:
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; }
Several lines below that code, I try to use this class:
void foo(SplitStream & out) { double some_double = 1.23; out << "bar" << some_double << std::endl; }
And I get this rather enigmatic error:
... error C2678: binary '<<' : no operator found which takes a left-hand operand of type 'const SplitStream' (or there is no acceptable conversion) ...
What am I doing wrong? I tried to define operator<< without consts, and it didn't compile either.
The immediate problem is that std::endl isn't an object but a function template declared something like this:
template <typename cT, typename Traits> std::basic_ostream<cT, Traits>& endl(std::basic_ostream<cT, Traits>&);
To use a function pointer like this, the template arguments need to be deduced. To this end, the class std::basic_ostream<cT, Traits> declared suitable overloads for 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>&));
This way, the compiler can deduce the correct instantiation when the std::endl function is referenced.
However, all that is utterly irrelevant because what you are trying to do is better done entirely differently! You should create a suitable stream buffer and use a reasonably constructed std::ostream with this custom stream buffer. Below is a complete example how to do it properly (I had posted it before but only a couple dozens times...):
#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"; }
这篇关于C ++模板运算符编译错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!