Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Template integer parameter constructor

Tags:

c++

templates

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;
};
like image 339
Fred Avatar asked Feb 04 '14 12:02

Fred


People also ask

Can template class have constructor?

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.

Can a template be a template parameter?

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.)

Can we pass Nontype parameters to templates?

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.

What is template type parameter?

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.


2 Answers

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.

like image 67
bobah Avatar answered Oct 19 '22 19:10

bobah


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
like image 37
Mike Seymour Avatar answered Oct 19 '22 18:10

Mike Seymour