Семинар 14 (04.12.2015)
Шаблоны (templates)
Шаблоны функций
Базовый пример использования шаблонов функций:
template <typename T> T add(const T & a, const T &b) {
return a + b;
}
add
- функция возвращающая результат сложения двух значений.
Функция применима к любым типам, для которых определён operator+
и конструктор копирования
(копирование происходит при возврате значения).
Ключевые слова typename
и class
в аргументах шаблона равнозначны.
Использование шаблонной функции add
:
int main() {
std::cout << add(2, 3) << std::endl; // OK: 5
std::cout << add(2.0, 3.5) << std::endl; // OK: 5.5
std::cout << add(std::string("foo"), std::string("bar")) << std::endl; // OK: "foobar"
std::cout << add(3, 2.5) << std::endl; // Error: missmatch types int and double
std::cout << add<double>(3, 2.5) << std::endl; // OK: cat all arguments to double
}
Заметьте, что использование разных типов приводит к ошибке компиляции. (Но можно указать тип аргументов явно)
Что делать, если нужно складывать аргументы разных типов? "Простое" решение - указывать тип возвращаемого значения явно при использовании шаблона:
template <class A, class B, class C>
C add(const A & a, const B & b) {
return a + b;
}
int main() {
std::cout << add<double, int, double>(2.5, 3) << std::endl;
}
Но лучше воспользоваться автоматическим выводом типов.
Ключевое слово decltype
в новых версиях стандарта C++
позволяет вычислять и использовать тип выражения:
double x = 5.5;
decltype(x) y = x; // type of `x` is 'double'
decltype
можно использовать для вычисления возвращаемого значения,
но следующий не скомпилируется:
template <class A, class B>
decltype(a + b) add(const A & a, const B & b) {
return a + b;
}
так как a
и b
определены после того, как они использованы в decltype
.
Поэтому добавлена возможность использовать следующий синтаксис:
template <class A, class B>
auto add(const A & a, const B & b) -> decltype(a + b) {
return a + b;
}
int main() {
add(2, 2.5); // returns double as expected
}