I don't understand the following constructor (part of Qt library in src\corelib\tools\qstringbuilder.h), what does it mean and how does it work?
class QLatin1Literal
{
public:
int size() const { return m_size; }
const char *data() const { return m_data; }
template <int N>
QLatin1Literal(const char (&str)[N])
: m_size(N - 1), m_data(str) {}
private:
const int m_size;
const char * const m_data;
};
We can use this technique in our template code to create default constructors. For any generic type, T, we can explicitly call its default constructor. Our Measurement template can now be constructed with any type that has a default constructor.
A template argument for a template template parameter is the name of a class template. When the compiler tries to find a template to match the template template argument, it only considers primary class templates. (A primary template is the template that is being specialized.)
Template classes and functions can make use of another kind of template parameter known as a non-type parameter. A template non-type parameter is a template parameter where the type of the parameter is predefined and is substituted for a constexpr value passed in as an argument.
A template parameter is a special kind of parameter that can be used to pass a type as argument: just like regular function parameters can be used to pass values to a function, template parameters allow to pass also types to a function.
The constructor is taking string literal as an argument. What you see is just a syntax to declare a template for this.
With such constructor m_size can be found in O(1) opposed to O(strlen(str)) required otherwise with a non-template constructor taking char const*
as an argument.
A thing to remember of is for each string length there will be an instance of template generated by compiler so you may end up having quite a few instantiations of this template in your library/binary/object files.
The constructor argument is a reference to an array of N
characters. It initialises m_data
to point to the first character, and m_size
to one less than the size of the array.
A string literal, like "hello"
, is an array of characters containing those in the string, followed by a zero-valued terminator. So, if the constructor is called with one of those:
QLatin1Literal lit("hello");
assert(lit.size() == strlen("hello")); // SUCCESS: m_size is inferred as 5
it will infer a value of 6 for N
(since the array contains the five characters of "hello", plus the terminator), and initialise m_size
to 5 (the actual string length).
Beware that this could go wrong if the array isn't actually a string literal; for example:
char buffer[1000] = "hello"; // array size is larger than string+terminator
QLatin1Literal lit(buffer);
assert(lit.size() == strlen("hello")); // FAIL: m_size is inferred as 999
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