Domanda

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 strings 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::endls. 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::endlin 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.
È stato utile?

Soluzione

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.

Altri suggerimenti

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);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top