return sizeof... (Args);
}
Как и для обычного оператора sizeof, результатом sizeof... является константное выражение, которое, следовательно, можно использовать для задания границ массива и т.п.
А.7. Автоматическое выведение типа переменной
С++ — статически типизированный язык: тип любой переменной известен на этапе компиляции. Более того, программист обязан указать тип каждой переменной. В некоторых случаях имена оказываются очень громоздкими, например:
std::map
std::map
iter = m.find("my key");
Традиционно для решения этой проблемы использовались псевдонимы типов (typedef), позволяющие сократить длину идентификатора типа и избавиться от потенциальных проблем несовместимости типов. Этот способ работает и в C++11, но появился и новый: если переменная инициализируется в объявлении, то в качестве ее типа можно указать auto. Тогда компилятор автоматически выведет тип переменной из типа инициализатора. Следовательно, приведенный выше пример итератора можно записать и так:
auto iter = m.find("my key");
Спецификатор auto необязательно употреблять изолированно; его можно использовать в сочетании с другими спецификаторами для объявления const-переменных, а также указателей и ссылок. Вот несколько примеров объявления переменных с помощью auto и дополнительных конструкций:
auto i = 42; // int
auto& j = i; // int&
auto const k = i; // int const
auto* const p = &i // int * const
Правила выведения типа переменной основаны на правилах, применяемых в другом месте языка, где выводятся типы: параметры шаблонов функций. В объявлении вида
Какое-то-типовое-выражение-включающее-auto
var = some-expression;
переменная var имеет тот же тип, который был бы выведен, если бы она встречалась в качестве параметра шаблона функции, объявленного с таким же типовым выражением, только auto заменяется именем типового параметра шаблона:
template
void f(type-expression var);
f(some-expression);
Это означает, что тип массива сводится к указателю, а ссылки опускаются, если только в типовом выражении переменная явно не объявлена как ссылка. Например:
int some_array[45];
auto p = some_array; // int*
int& r = *p;
auto x = r; // int
auto& y = r; // int&
Это позволяет существенно упростить объявление переменных, особенно в случаях, когда полный идентификатор типа очень длинный или даже неизвестен (например, тип результата вызова функции в шаблоне).
А.8. Поточно-локальные переменные
У поточно-локальной переменной имеется отдельный экземпляр в каждом потоке программы. Для объявления поточно-локальной переменной служит ключевое слово thread_local. Поточно-локальными могут быть переменные с областью видимости пространства имен, статические члены классов и локальные переменные. Говорят, что они имеют
thread_local int x;←┐Поточно-локальная переменная в
│области видимости пространства
│имен
class X │Поточно-локальная
{ │статическая пере-
static thread_local std::string s;←┘менная-член класса
};
│Необходимо
static thread_local std::string X::s;←┘определение X::s
void foo() {
│Поточно-локальная
thread_local std::vectorлокальная переменная
}