[Development] User-defined literals for QString (and QByteArray)
Thiago Macieira
thiago.macieira at intel.com
Fri Mar 5 20:04:57 CET 2021
On Friday, 5 March 2021 04:40:24 PST Lars Knoll wrote:
> I wish we had a good way of adding that overloaded constructor to QString.
> Unfortunately, we have lots of API that is overloaded on both QString and
> QStringView. Adding the constructor to QString will then cause ambiguities
> wherever we have overloaded API taking both a QString and a QStringView.
>
> I wish there was a way to tell the compiler to prefer one conversion over
> the other ("if you have the choice, always use QStringView and not
> QString”), but C++ doesn’t have a way to do that.
There an ugly way. By making one of the two a template function, it lowers in
priority for matching.
template <typename T>
std::enable_if_t<std::is_same_v<T, QString>> f(const T &);
void f(QStringView);
void g()
{
f(u"Hello");
}
<https://gcc.godbolt.org/z/bMhGrx>
The problem is that changing existing QString methods to be templates is
binary incompatible. That means we can't add QStringView overloads where
QString parameters already exist and are out-of-line (remember: any non-
template method in an exported class is out of line for the purposes of BC).
Another one is to add the constructor to QString, but make it explicit. So you
can still work on char16_t literals, but you may need to wrap it on QString():
void g1()
{
f(QString(u"Hello"));
}
<https://gcc.godbolt.org/z/oeceEW>
The problem in this one is that it's far easier to write f("Hello") than the
slightly more efficient f(QString(u"Hello")). For this, an UDL would help.
And it's really only *slightly* more efficient. Previous benchmarks have shown
that going through the UTF-8 decoder adds 2-5% loss compared to memcpy() and
that time is dwarfed anyway by the cost of allocating memory.
--
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel DPG Cloud Engineering
More information about the Development
mailing list