2014-02-04 2 views
10

Я не понимаю следующий конструктор (часть библиотеки Qt в src \ corelib \ tools \ qstringbuilder.h), что это значит и как это работает?Шаблон целочисленный конструктор параметров

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; 
}; 
+0

N здесь нет шаблон шаблона. – sajas

ответ

11

Конструктор принимает строковый литерал как аргумент. То, что вы видите, является просто синтаксисом для объявления шаблона для этого.

С таким конструктором m_size может быть найден в O (1), противоположном O (strlen (str)), который требуется в противном случае с конструктором без шаблона, принимающим char const* в качестве аргумента.

Следует помнить, что для каждой длины строки будет экземпляр шаблона, сгенерированного компилятором, чтобы в конечном итоге у вас было много экземпляров этого шаблона в библиотечных/двоичных/объектных файлах.

+1

+1, но я бы сказал, что эти «экземпляры» фактически встроены и никогда не превращаются в двоичный файл как автономный. – Angew

+0

@Andrew - согласитесь, при наклонном ударе будет только небольшое увеличение времени компиляции, а не двоичного размера. – bobah

+1

Еще одна важная вещь, которую следует помнить здесь, - это особый корпус, когда присутствует перегрузка 'const char *', которая будет выбрана над шаблоном, даже если она выглядит лучше (без необходимости распада). – PlasmaHH

3

Это означает, что str является ссылкой на массив постоянных N символов. Это просто означает, что конструктор принимает в качестве аргумента массив символов, например, как строковый литерал.

8

Аргумент конструктора является ссылкой на массив из N символов. Он инициализирует m_data, чтобы указать на первый символ, а m_size - на один меньше, чем размер массива.

Строковый литерал, такой как "hello", представляет собой массив символов, содержащий символы в строке, за которым следует нулевой знаменатель. Таким образом, если конструктор вызывается с одним из тех, кто:

QLatin1Literal lit("hello"); 
assert(lit.size() == strlen("hello")); // SUCCESS: m_size is inferred as 5 

он будет считать значение 6 для N (так как массив содержит пять символов «привет», а также терминатора), и инициализируются m_size к 5 (фактическая длина строки).

Остерегайтесь, что это может пойти не так, если массив фактически не является строковым литералом; например:

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 
Смежные вопросы