GNOME Bugzilla – Bug 506394
Compose without format string
Last modified: 2009-01-08 17:46:39 UTC
It is not possible to compose without format string. Error occurs if only a literal string or numeric constant or variable is given. In my humble opinion it would be easier to use the compose API if it was possible. I'd suggest something like the following: Index: glib/glibmm/ustring.h =================================================================== --- glib/glibmm/ustring.h (revision 490) +++ glib/glibmm/ustring.h (working copy) @@ -609,6 +609,15 @@ //! @name Message formatting. //! @{ + /* + * @param a1 The argument to substitute for "%1". + * @return The substituted message string. + * @throw Glib::ConvertError + */ + template <class T1> + static inline + ustring compose(const T1& a1); + /*! Substitute placeholders in a format string with the referenced arguments. * The template string should be in <tt>qt-format</tt>, that is * <tt>"%1"</tt>, <tt>"%2"</tt>, ..., <tt>"%9"</tt> are used as placeholders @@ -1240,7 +1249,6 @@ public: explicit inline Stringify(const T& arg) : string_ (ustring::format(arg)) {} - explicit inline Stringify(const char* arg) : string_ (arg) {} inline const ustring* ptr() const { return &string_; } }; @@ -1261,6 +1269,16 @@ template <class T1> inline // static +ustring ustring::compose(const T1& a1) +{ + const ustring::Stringify<T1> s0 (a1); + + const ustring *const argv[] = { s0.ptr() }; + return ustring::compose_argv("%1", G_N_ELEMENTS(argv), argv); +} + +template <class T1> +inline // static ustring ustring::compose(const ustring& fmt, const T1& a1) { const ustring::Stringify<T1> s1 (a1); Index: examples/compose/main.cc =================================================================== --- examples/compose/main.cc (revision 490) +++ examples/compose/main.cc (working copy) @@ -32,7 +32,7 @@ const int i = int(a / (a + b) * 40.0); std::cout - << ustring::compose("%1 is lower than %2.", a, b) + << ustring::compose(a) << ustring::compose(" is lower than ") << ustring::compose(b) << ustring::compose('.') << std::endl << ustring::compose("%2 is greater than %1.", a, b) << std::endl
Can't you just use ustring::format() if you don't want to compose?
You're right. The problem is not so serious in a simple case, when you want to write out the value of a variable. Actually, I've tried to write a debug macro with variable number of arguments, so I haven't got information about the existence of the format string. Example: #include <glibmm.h> #include <iostream> #define debug(format, ...) std::cout << Glib::ustring::compose(format, ## __VA_ARGS__) int main(int, char**) { const char *constant_string = "constant string"; Glib::init(); debug("literal string\n"); debug("%1\n", constant_string); debug("%1 %2\n", "formatted", "string"); return 0; } The patch in comment 0 compose API would be more printf-style, but I don't know whether it is a goal.
So, Daniel, is this patch something that we want?
Sorry for the heavy delay. No, I don't think this patch is appropriate. I agree with the intent to make the API more orthogonal. However, the interpretation of the single-argument compose(arg) as compose("%1", arg) is wrong. Rather than no format string, this overload would take _only_ a format string and nothing else. That's also the way printf() works -- there is no printf() without a format string. So it would look like this: ustring::compose(const ustring& fmt) { return ustring::compose_argv(fmt, 0, 0); } Which is, apart from checking the format string for incorrect argument references, essentially the same as simply ustring::compose(const ustring& fmt) { return fmt; } We might want to add this for reasons of orthogonality, but it isn't terribly important. It wouldn't break API or ABI though, as it's just a trivial addition.
Szilárd, so do you agree that we can close this bug?
(In reply to comment #5) > Szilárd, so do you agree that we can close this bug? > I have no objection.
2009-01-08 Daniel Elstner <danielk@openismus.com> * glib/glibmm/ustring.h (ustring::compose): Add an overload which takes only a format string and no arguments to be substituted. It is essentially a null-operation as long as the format string does not contain any invalid argument references. Bug #506394. Closing.