>From: "Jason House" <[EMAIL PROTECTED]> > Terje Slettebų wrote: > > typedef std::vector<char> vector_char; > > > > vector_char values; > > > > // Fill with 'A', 'B', 'C' > > > > std::cout << io::format<vector_char>("[", "]", ", ", "\'", "\'") << values; > > > > Output: > > > > ['A', 'B', 'C'] > > > > However, is this overkill? > > It seems that way, especially considering that if it was a vector of > anything other than a fundamental type with std::cout << already defined > for it, you could add a second io::format<char>("\'","\'","") and it > would work.
Right. However, I've already implemented it, anyway, as an experimental feature. :) Besides, the two extra strings default to empty strings. > > Feedback is most welcome. > > Would possibly a function object for outputting the contained item be > better? [I first thought you meant a function object for outputting the _container_, not the elements, so I wrote the following section, before realising that you had meant for the elements. I address it afterwards] I've been thinking of the same, with regard to outputting the _container_ (not the element, itself). In an earlier posting, I mentioned the possibility of using function objects, as a way to generalising the handling of output. I also mentioned having the kind of function objects like BGL, i.e. "visitors". That is, rather than only overloading the operator(), it may provide several member functions, e.g.: class stream_visitor { public: void start(); void end(); void delimiter(); }; std::cout << format<type>(stream_visitor(...)); One could then provide a function object which does what it currently does. There are issues with this, however. I've been thinking long and hard about how to provide this functionality. The issue is that the functors has to be stored somewhere, and being accessible. With the current version, all the format objects are the same type, so you know its type when it's stored and retrieved. However, if arbitrary (generic) functors are stored, you don't know its type, when you access it, when performing output. It's similar to trying to store different types in the same std::vector. There are solutions to this, and one is to use a common interface, and all functors inherit from that interface, and override the virtual functions. That would let you store them using a pointer to the interface. However, this means the overhead of a virtual function call per call to the member functions above. This may not be that much, but it's still also the issue that generic functors can't be used - they all have to inherit from the same interface. For this reason, I found that this could be a possible later addition, if we find that the added flexibility is worth it. Also, the current syntax could still be kept as a convenience, by having an overloaded constructor taking the strings, and creating the functor. So a change may be backwards compatible. > Here's a possibly mutilated example (I've never actually used > function objects before): > > std::ostream delimitted_char(std::ostream out, char x, std::string > first, std::string last); > > std::cout << io::format<vector_char>("[", "]", ", ", > bind("\'", 4, bind("\'", 3, delimitted_char))) Yes, it's possible, but I this seems to make it more complex than simply using io::format<vector_char>("[", "]", ",", "\'", "\'"), with the two last strings defaulted to empty strings. > > There's yet another alternative way this may be done, using "placeholder" > > types, i.e.: > > > > std::cout << io::format<std::vector<_> >(...); // Sets the format for all > > vectors > > std::cout << io::format<_>(...); // Sets the format for all types (defaults) > > > > This would avoid hardcoding any defaults, as the user could change it. > > > > The output routines could then check the formats in the following order, > > e.g. for "std::vector<char>": > > > > If there's a format set for std::vector<char>, use it, else > > if there's a format set for std::vector<_> (all vectors), use it, else > > use format for _. > > > > Comments? > > I like it :) I found it quite neat, as well. :) Interestingly, one important contribution of libraries are concepts and idioms. Since "_" is used as placeholder other places, making it mean "any type" here is reasonably intuitive, as well. > Using just _ scares me a bit... It would have to have a good default :) Well, it doesn't matter that much, as all the formats are user-settable. The library may provide a setting for _, but it can easily be set to something else by the user, in the same way. In fact, the current version in the Files (the first upload), has as "defaults" that all strings are empty. So the defaults have existed from the beginning, anyway. After all, you have to use _some_ format to print types for which no explicit format has been set. Being able to set this default explicitly, rather than hardcoding it in the library, should therefore be a good thing. In fact, I've made an implementation of the above, yesterday, and I'll just make some more tests, and upload it to the Files section and Sandbox soon. I'll post about it here when that's done. Regards, Terje _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost