le Monday 30 August 2004 19:43, findlay@cosmic.utah.edu écrivit :
I've got some code that uses the format library to format output, not out of necessity, but rather out of a wanton enjoyment derived from using the syntax, having lately (relatively) discovered boost, prefering the boost::format simple syntax to the posix printf and std::ostringstream flavored solutions. The "problem" I have is that for the output of every double, I have to specify the precision:
int main() { cout << setprecision(18); cout << format("Bunner p' air: %1% torr\t\tN$_2$: %2% torr\n" " C air: %3%\t\tN$_2$: %4%") % group(setprecision(18), bunner::air::pp_av) % group(setprecision(18), bunner::N2::pp_av) % group(setprecision(18), bunner::air::c_av) % group(setprecision(18), bunner::N2::c_av) << endl; //...
return 0; }
Is there a graceful solution, or am I using this library beyond what it was intended for?
Well, making manipulators *non* sticky was in fact a desired feature of the library. Quite a bit of work is done to insure that. Letting manipulators (and whatever other stream modification) stack from one argument formatting to the next would be much easier.. In your case, using the stream directly, with a sticky setprecision, seems natural. If you really want to use format, you can either : A/ pass the precision via printf-style syntax (at each item), e.g. : cout << format("Bunner p' air: %|1$.18| %|2$.18|") % bunner::air::pp_av % bunner::N2::pp_av << endl; Does this solution fit you ? B/ define a number + format-style wrapper class, e.g. 'StyledNumber', on which you overload operator<<(stream&, ..) so that it temporarily overrides the stream's precision parameter, and them format StyledNumber objects : cout << format("Bunner p' air: %1% %2%") % StyledNumber(bunner::air::pp_av) % StyledNumber(bunner::N2::pp_av) << endl; here, it's not much shorter than the original version, but if you replace calls to the constructor by calls to short-named wrapper function, it can improve the situation a bit and you get all the flexibility you want I can think about adding this feature as a member function to boost::format that would apply one manipulator to all items in one go, like : cout << format("Bunner p' air: %1% %2%").stick(setprecision(18)) % bunner::air::pp_av % bunner::N2::pp_av; Is it what you'd need ? There's already an undocumented member function, 'modify_item', that applies a manipulator to one "format item", so 'stick' would just have to do the same, except for all the items. The only problem is : it's only able to clone the manipulator's effects on *standard* stream parameters, while a user-defined manipulator could very well act on unknown user-defined stream parmaters (think xalloc, etc..). So such a feature would have to be documented along with the details on its limits, and interfaces full of functions-with-special-cases are better avoided IMO. Anyway I need to take some time and finally document the undocumented functions (modify_item, bind_arg, etc..), and then I might add a 'stick' function along those. In the meantime, you can use the 'modify_item' function to define an external 'stick' function. -- Samuel