问题
C++
This is an attempt to make a class that mimics the output behavior of using the <<
operator of an ofstream
, as far as being able to use std::endl
and write string
s is concerned. The class has a single data member, the ofstream
pointer. The class has two overloaded <<
operators, one that takes an std::string
and another that takes a pointer to a function, whose argument is an ostream
reference and returns an ostream
reference. That is the signature of std::endl
, according to this. Technically, the below program works with the given input. It is able to print to file, two lines of text separated by two std::endl
s. However, I want my non-string parameter overloaded <<
operator to accept std::endl
only, not something that merely matches its signature. I tried various combinations of placing std::endl
in the argument list, with and without *
and with and without &
, but I got compiler errors for every combination. C++11 answers are also welcome.
#include <fstream>
#include <iostream>
#include <string>
class TextOut
{
public:
TextOut(std::ofstream* ofsPar) : ofs(ofsPar) {}
TextOut& operator<<(std::string s)
{
*ofs << s;
return *this;
}
TextOut& operator<<(std::ostream& (*endlPar) (std::ostream& os))
{
*ofs << std::endl;
return *this;
}
private:
std::ofstream* ofs;
};
int main()
{
std::cout << "Enter filename: ";
std::string filename;
std::cin >> filename;
std::ofstream myofstream(filename.c_str());
TextOut myTextOut(&myofstream);
myTextOut << "Hello," << std::endl << std::endl << "spacious world.";
return 0;
}
Output:
Hello,
spacious world.
回答1:
If I look at my ostream header file I see this for endl:
template<typename _CharT, typename _Traits> inline basic_ostream<_CharT, _Traits>&
endl(basic_ostream<_CharT, _Traits>& __os)
{
return flush(__os.put(__os.widen('\n')));
}
so it looks like you would need to inherit from basic_ostream
to make this work. Not sure you really want to do that.
回答2:
As far as I know there is no way to enforce a parameter to be a specific value at compile time.
If compile-time enforcement is not a requirement, you could use a simple assert like this to enforce that the parameter is std::endl
:
assert(static_cast<std::ostream& (*) (std::ostream& os)>(&std::endl) == endlPar);
来源:https://stackoverflow.com/questions/15215010/using-ofstream-wrapper-class-with-overloaded-operator-on-endl