Details
-
Suggestion
-
Resolution: Unresolved
-
P3: Somewhat important
-
None
-
5.3.0
-
None
Description
Suppose you have a format string
QString formatString = "Object '%1': foo = %2, bar = %3"
where %2 and %3 are some integer arguments.
There are currently 2 ways to substitute arguments for it:
1. formatString.arg(name, QString::number(1), QString::number(2));
2. formatString.arg(name).arg(1).arg(2);
Since the first way seems too long, many users prefer the second one. And here comes the problem: the second way is unsafe if "name" is not sanitized, because "name" itself may contain "%N" sequences!
To solve this problem I propose to add some other function, say "args" or "substitute" or "format", that gets variadic template argument list and works just as "arg" would work if every argument is converted to QString first. (We can always use an overloaded function of 1, 2, 3, etc. template arguments instead of variadic templates to stick to C++03.)
In other words, it should work like the following "args" function:
template<typename T> QString toQString(const T& v) { QString out; QTextStream stream(&out); stream << v; return out; } template<typename... Values> QString args(const QString& format, Values... values) { return format.arg(toQString(values)...); }
Of course, there are some differences between the function I propose to implement and the "args" function above:
1. The real "args" function should be a QString member.
2. The real "args" function should fail if "%N" placeholder sequence contains gaps or does not start with "%1", because it is not supposed to be used in a chain.
3. The "toQString" function may be specialized for standard classes to enhance performance.
If such a function is added, the former "arg" method can be marked as obsolete.
The benefits of the suggested approach are:
1. Increased safety: the case when arguments contain "%N" themselves will be always handled correctly.
2. Even shorter expression in simple cases when numbers do not require custom formatting, like:
formatString.args(name, 1, 2);
(On the other hand, the expression will become longer if some numbers should be formatted in a non-default way, because the user will have to write QString;:number by hands.)
3. Extensibility: it will be possible to print user-defined types via the "args" function.