3

Let's say that I have some in-house framework for files and streams. I have IOutputStream interface class with write(char const *buffer, size_t size) and flush(). I have a tool, called Printer which can be used with any instance of IOutputStream descendants. Then I have Printer & operator<<(T x) style methods, where T x is the data (or a reference or a pointer to it) to be written.

For example Printer & operator<<(int x) will translate x to string, and will call the referenced output stream's write(...) function for real.

Let's see the problem! Invocation: printer << "appletree";. It calls Printer & operator<<(char const *s). For this kind of usage, I have to call an strlen(s) to determine the size, and after that I can call the final step. This is rather insane since I know the length of appletree at compile time.

Are there any good practice for this? How STL's ostream plays with titerals?

Notinlist
  • 16,144
  • 10
  • 57
  • 99
  • Is the call to `strlen` a performance bottleneck? Personally, I would just take the hit of the `strlen` call to keep your code simple to read (assuming it's not a performance hit). – deanWombourne Sep 07 '12 at 12:23
  • See this [answer to another question](http://stackoverflow.com/a/11639305/597607) which shows that sometimes the compiler will be able to compute `strlen("some text")` at compile time. Just call it, and hope for the best. In your case, I bet the printer will be the bottleneck anyway. – Bo Persson Sep 07 '12 at 12:29

2 Answers2

6

Since string literals have type const char(&)[], you could add an overload for them:

template<size_t n>
Printer& operator<<(const char (&cstring)[n]) {
    write(cstring, n - 1);
}
mfontanini
  • 21,410
  • 4
  • 65
  • 73
3

How about

template<std::size_t Size>
Printer& operator << (const char (&s)[Size]);
ForEveR
  • 55,233
  • 2
  • 119
  • 133