Почему необязательные параметры не работают с шаблонами?

Почему дополнительные параметры с шаблонными функциями не работают в C ++?

(Уточнение: я надеюсь понять Зачем C ++ был спроектирован так, что это было бы невозможно.)

#include <iostream>
template<class T1, class T2> T1 inc(T1 v, T2 u = 1) { return v + u; }
int main() { std::cout << inc(5); }

prog.cpp: В функции ‘int main()’: ошибка: нет подходящей функции для вызова ‘inc(int)’

2

Решение

Вы неправильно поняли. Аргументы по умолчанию не участвуют в выводе аргументов:

Аргументация вывод первый, как часть выбора желаемой перегрузки, и затем аргументы по умолчанию этой перегрузки заполняются при необходимости.

3

Другие решения

То, что Kerrek SB сказал правильно, компилятору просто не хватает для вывода T2 (из того, что ему разрешено делать из стандарта).

В этом конкретном случае вы, вероятно, можете исправить это, используя только один аргумент шаблона для всего, т.е.

template< class T > T inc( const T v, const T u = 1 ) { return v + u; }
2

Аргументы по умолчанию не участвуют в процессе вывода (только для разрешения перегрузки, и правила очень трудно запомнить — всегда делайте это простым).

Для достижения желаемого вы можете предоставить дополнительную перегрузку:

template <class T1, class T2> T1 inc(T1 v, T2 u) { return v + u; }
template <class T> T inc(T v) { return v + T(1); }
1

Шаблонные функции в C ++ генерируются во время компиляции и генерируются только в случае необходимости. Таким образом, вы можете получить функцию, сгенерированную так:

inc( int, int );

Это будет версия T1 = int и T2 = int. Компилятор может неявно определить тип, если вы передадите параметры для каждого аргумента шаблона, поэтому:

int a = 1;
int b = 2;
inc( a, b );

Компилятор может генерировать функцию, подобную приведенной выше, во время компиляции, поскольку он может сделать вывод, что T1 = int и T2 = int. Однако, если вы делаете то, что делаете:

inc( 5 );

Компилятор может определить, что T1 = int, но он не может определить, что такое T2. Таким образом, никакая функция не генерируется, и вы получаете ошибку о том, что функция не существует. Это может быть исправлено, если вы используете один параметр шаблона:

template<class T> T inc(T v, T u = 1) { return v + u; }

Или если вы предоставляете перегрузку:

template<class T> T inc(T v) { return v + 1; }

Есть и третий способ:

inc<int, int>( 5 );

Но я думаю, это не то, что вы хотите …

0
По вопросам рекламы [email protected]