2012-05-25 2 views
3

Шаблон функции:Почему нам нужно ключевое слово template в C++?

template<class T> T 
max(T a, T b){return (a > b)? a: b;} 

при использовании его:

max<int>(a, b); // Yeah, the "<int>" is optional most of the time. 

, но если вы позволите, мы можем написать шаблону так:

T max<class T>(T a, T b){return (a > b)? a: b;} 
//I know the return type T is not in its scope, don't focus on that. 

Таким образом, мы можем сохранить ту же форму декларации и использования, как и обычная функция. и даже не нужно вводить и вводить ключевое слово «шаблон». Я думаю, что шаблон шаблона будет таким же? Так есть ли другая причина, чтобы шаблон стал той формой, которую мы знаем сегодня?

я изменил форму, так что вы не сосредоточены на тип возвращаемого значения:

auto max<class T>(T a, T b) -> T {return (a > b)? a: b;} 
//This is C++11 only and ugly i guess. 
//The type deduce happens at compile time 
//means that return type really didn't to be a problem. 
+0

Это просто синтаксис, который был выбран. Я считаю, что в этом нет никакой реальной причины. Это простое решение. –

+2

Вы опоздали всего на несколько месяцев, когда их приняли C++ 11. Теперь вам нужно ждать следующие 20 лет. –

+0

Я не помню, чтобы такой вариант рассматривался в _Design и Evolution of C++ _, что является AFAIK лучшим источником для обоснования для вещей, принятых в то время (около 20 лет назад). – AProgrammer

ответ

2

Непосредственный ответ, который приходит мне на ум:
Просто потому, что кто-то выложил предложение шаблонов сказал поэтому и никто в комитете по стандартам не чувствовал, что набирать лишние цифры 8 будет накладными расходами.

На другой ноте:
Синтаксис шаблонов является сложным и пугающим, чтобы начать с, убедившись, наличия ключевого слова template делает его более понятным для читателя кода, что они имеют дело с шаблонами, а не какой-либо из другие животные, предоставленные C++, или любые конструкции, специфичные для реализации (читайте расширения компилятора).

1

Я верю, что проблема заключается в простоте реализации компилятора: любые имена, используемые в C++, должны быть объявлены как минимум, прежде чем использоваться, чтобы помочь компиляторам разобраться с началом (по той причине, о которой я не знаю). Это одна из причин, по которой у вас есть странный новый синтаксис для объявления функций, которые позволяют определять тип возвращаемого значения после аргументов.

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

2

вы должны объявить T, прежде чем использовать его, так что это действительно должно быть

<class T> T max(T a, T b){return (a > b)? a: b;} 

Но тогда его не ясно, что <class T> это - компилятор, скорее всего, запутался об этом. template спереди ясно показывает, что < не являются операторами, а скобки, в которых заключаются объявления типа.

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

+0

Есть языки, которые не нуждаются в 'template ' вообще, и они в порядке. – hamstergene

+0

И пример ...? – cschwan

+2

Скала, ржавчина. Есть довольно много, я просто не помню много. Это определенно * не обязательно. BTW, в C++ иногда можно использовать идентификатор перед его объявлением (рассмотрите методы встроенного класса, вызывающие друг друга: им не требуются передовые объявления), поэтому даже для C++ «T должно быть объявлено первым» звучит как слабая причина. – hamstergene

1

Вы быстро попасть в проблемы при разборе с этим подходом:

template <typename> int f(); // Current declaration syntax, type template argument. 
template <int> int f();  // Current declaration syntax, non-type template argument. 

void f<class>(); // New declaration syntax, type argument. 
void f<int>(); // New declaration syntax, non-type argument. 
(void) f<int>(); // (void) is a cast , f is instantiation of f<class> with type int. 
+0

Это не проблема. '(void) f ();' будет рассматриваться как то же, что и 'template void f();' если он один. И будет рассматриваться как приведение при использовании в качестве rvalue. То же самое касается нормальной работы. –

+0

@Mike: Попробуйте разобрать синтаксический разбор недвусмысленно. Что относительно 'f f ();'? 'f (* f )();'? '(f *) (* f )();'? – MSalters

+0

'f ' будет типом, который предопределен, я думаю, потому что в правой части его нет скобок. Я не уверен, что имена классов и имена функций могут быть перегружены или нет. Если это разрешено, это будет шаблон функции так же, как «шаблон f f();', второй - указатель на первый, а третий - тот же, что и второй, за исключением того, что возврат тип отличается, когда они одни. И нет никакого способа сделать кого-либо из них отличным. –

Смежные вопросы