шаблон функции подписи


Что определяет, является ли два шаблона функции деклараций объявлять один и тот же шаблон, или перегрузки таким же именем?

Начало ответа на этот вопрос встречается в 3.5p9:

Two names that are the same (Clause 3) and that are declared in different scopes shall denote the same variable, function, type, enumerator, template or namespace if

  • both names have external linkage or else both names have internal linkage and are declared in the same translation unit; and

  • both names refer to members of the same namespace or to members, not by inheritance, of the same class; and

  • when both names denote functions, the parameter-type-lists of the functions (8.3.5) are identical; and

  • when both names denote function templates, the signatures (14.5.6.1) are the same.

Подпись номера-шаблон функции, не являющейся членом является (1.3.17):

signature

<function> name, parameter type list (8.3.5), and enclosing namespace (if any)

[Note: Signatures are used as a basis for name mangling and linking. -- end note]

parameter-type-listcv-qualifiers

Указанные два раза уже определен в разделе 8.3.5p5. Этот пункт описывает, как фактические типы параметров функции настраиваются из заявленных видов, заменять массивы и функции с указателями, и отбросив верхний уровень . Затем,

The resulting list of transformed parameter types and the presence or absence of the ellipsis or a function parameter pack is the function's parameter-type-list.

parameter-type-list

Так в шаблоне дело, явно концептуальной семантической перечень видов (плюс, возможно, необычные концовки), а не последовательность лексем или синтаксических конструкции. И вот, как мы и ожидали, нарушение ОУС, поскольку оба определения определяют одну и ту же функцию:

void f(int, int*) {}void f(int p, decltype(p)*) {}

В случае шаблонов, у нас есть (1.3.18):

signature

<function template> name, parameter type list (8.3.5), enclosing namespace (if any), return type, and template parameter list

Теперь считаем:

template<typename T> void g(int, int*, T, T*) {}               // #1// template<typename T> void g(int p, decltype(p)*, T, T*) {}  // #2template<typename T> void g(int, int*, T q, decltype(q)*) {}   // #3
qpdecltype(q)

г -с std=с 0х версия 4.6.3 жалуется на то, что определения № 1 и № 2 определяют одну и ту же функцию, но не имеет никаких проблем, принимая #1 и #3 в качестве перегрузки. (Он также думает, что #3-это более специализированная, чем #1, и нет никакого способа, чтобы позвонить #1, но это вопрос касательной.) Основное различие между #2 и #3-это типа-зависимые и нет. Поэтому я предполагаю, что значение не может быть определено до тех пор, пока не будет создан шаблон? Это поведение гарантируется стандартом?

parameter-type-list

Для шаблонов функции, значение должно быть разрешено включать в параметры шаблона, которые еще не были заменены инстанцировании, и поэтому зависимые имена и все такое. Но что делает его сложным, если это возможно, чтобы знать, могут ли два объявления эквивалентны.

equivalentequivalentfunctionally equivalentfunctionally equivalent

Подобный вопрос решается 14.5.6.1 пунктах 5-6, которые определяют выражения и функции шаблона объявления (та же последовательность знаков, за исключением того, что отдельные заявления могут использовать различные идентификаторы для параметров шаблона), выражения и функции шаблон заявления (же после создания экземпляра), с требованием:

If a program contains declarations of function templates that are functionally equivalent but not equivalent, the program is ill-formed; no diagnostic is required.

Пример из пункта 5 демонстрирует безопасно эквивалент шаблоны функций:

template <int I, int J> void f(A<I+J>);  // #1template <int K, int L> void f(A<K+L>);  // same as #1

и пример из пункта 7 демонстрирует нарушение этого правила:

// Ill-formed, no diagnostic requiredtemplate <int I> void f(A<I>, A<I+10>);template <int I> void f(A<I>, A<I+1+2+3+4>);
gT*decltype(q)*

Но это не относится к приведенному выше примеру функции. и можно считать эквивалентными по некоторым аналогичным определением эквивалентности типа, но раздел 14.5.6.1 только заклинания, замена выражений, а не типы.