I have found this in Qt's Doc:
QStringViews should be passed by value, not by reference-to-const:
and they give the following example:
void myfun1(QStringView sv); // preferred
void myfun2(const QStringView &sv); // compiles and works, but slower
How is this possible?
The reason is simple: if you passed by value, a copy of the object had to be made and, except for very small objects, this is always more expensive than passing a reference.
Use pass-by-reference if you want to modify the argument value in the calling function. Otherwise, use pass-by-value to pass arguments. The difference between pass-by-reference and pass-by-pointer is that pointers can be NULL or reassigned whereas references cannot.
From what I understand: when you pass by value, the function makes a local copy of the passed argument and uses that; when the function ends, it goes out of scope. When you pass by const reference, the function uses a reference to the passed argument that can't be modified.
The QString class provides an abstraction of Unicode text and the classic C '\0'-terminated char array. More... All the functions in this class are reentrant when Qt is built with thread support.
QStringView
is typically used in high-performance code where creating actual QString
objects would be slow due to the memory allocation involved. I optimized QStringView
so that it is as performant as handling a (const QChar*, size_t)
manually. I even went to the length of having member function calls hand off inline to free functions, passing *this
by value. All this is to avoid forcing QStringView
objects onto the stack, or, more generally, into memory.
In virtually all C++ compilers, a QStringView
object is represented as a pair of CPU registers, and many C++ ABIs (sadly, excluding Windows) support passing such types in CPU registers to functions. If you wrote the member function naïvely, with an implicit this
parameter as the address of the object, calling such a function out-of-line would force the compiler to allocate a QStringView
object on the stack to be able to pass its address as the first argument of the member function.
There's a second argument for pass-by-value: there are less aliasing problems. As a reference type, QStringView
exhibits that problem anyway, but consider std::complex
: Take
std::complex &operator*=(std::complex &lhs, const std::complex &rhs);
(template args omitted for brevity). This can be called like this:
std::complex c = 3 + 4i;
c *= c;
If you naïvely implement operator*=
as if it was a mathematical function:
auto r = real(), i = imag();
m_real = r * other.real() - i * other.imag();
m_imag = r * other.imag() + i * other.real();
you would have clobbered other.real()
after the first line, thus calculating a wrong result (yes, people do write this code in production). Passing the rhs
by value makes the problem go away.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With