Параметры шаблона по умолчанию в использовании-объявлении и реализации - PullRequest
0 голосов
/ 12 октября 2018

Редактировать:
По-видимому, GCC позволяет создавать экземпляр шаблона класса без списка параметров (когда параметры по умолчанию), что не соответствует (Clang совместим).
I 'Я угадываю причину, по которой скобки требуются (даже если список параметров пуст), состоит в том, чтобы четко указать, что это экземпляр шаблона, а не фактический тип.
Поэтому я направляю свой первоначальный вопрос к различиям междуслучаи с шаблоном класса и шаблоном функции: почему во втором фрагменте разрешено вызывать a без скобок, в отличие от создания экземпляра A в первом фрагменте?И почему это не разрешено для b?


Оригинал:
Шаблон класса с только параметрами по умолчанию может быть создан без какого-либо списка параметров (см. A ниже).
Однако, если псевдоним этого шаблона класса определяется с помощью объявления использования в качестве шаблона с теми же параметрами по умолчанию (см. B ниже), то для его создания требуется список параметров (возможно, пустой).
Аналогично, определениепсевдоним шаблона класса в качестве фактического типа (см. C ниже) требует список параметров (опять же, возможно, пустой).
Есть ли причина этого?
template<int i = 1>
struct A {
    operator int() { return i; }
};

template<int i = 2>
using B = A<i>;

// using C = A;    <-- error: missing template arguments after 'A'
using C = A<>;

int main() {
    A a; // Edit: Actually should require brackets: A<> a;
    // B b;    <-- error: missing template arguments before 'b'
    B<> b;
    C c;
}

Live onColiru

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

template<int i = 1>
auto a() { return i; }
// auto a() -> int { return i; }
// if the return type is specified, c can be defined as commented below

template<int i = 2>
auto b = a<i>;

// auto c = a;    <-- error: unable to deduce 'auto' from 'a'
auto c = a<>;

int main() {
    a();
    // b();    <-- error: missing template arguments before '(' token
    b<>();
    c();
}

Live on Coliru

Кроме того, существуют ли существенные различия между современными стандартами C ++ (C ++11 до C ++ 20)?Меня больше всего интересует дело C ++ 17, но я хотел бы знать, изменились ли эти вещи или произойдет ли это.
Из того, что я видел в C ++ 14, создание экземпляра шаблона класса требуетв любом случае список параметров, тогда как вызов шаблона функции - нет.И я не нашел различий между C ++ 17 и C ++ 2a с GCC.

1 Ответ

0 голосов
/ 12 октября 2018

Аргументы шаблона [temp.arg] / 4 (§12.3 / 4)

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

Та же формулировка для C ++ 17 в§17.3 / 4, для C ++ 14 и C ++ 11 в §14.3 / 4.

Явная спецификация аргумента шаблона [temp.arg.explicit] (§12.9.1 / 3) :

Если все аргументы шаблона могут быть выведены, все они могут быть опущены;в этом случае сам список пустых аргументов шаблона <> также может быть опущен.

Та же формулировка для C ++ 17 в §17.8.1 / 3, для C ++ 14 & C ++11 в §14.8.1 / 3.


Ваш

template<int i = 2>
auto b = a<i>;

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

...