Почему шаблон с единственно допустимым пустым пакетом вариов? - PullRequest
0 голосов
/ 29 ноября 2018

Что является обоснованием

temp.res # 8.3

(8) Действительность шаблона может быть проверена перед любой реализацией.[Примечание: Зная, какие имена являются именами типов, можно таким образом проверять синтаксис каждого шаблона.- примечание к концу] Программа некорректна, диагностика не требуется, если:
[..]
(8.3) для каждой действительной специализации вариационного шаблона требуется пустой пакет параметров шаблона, или

Это правило запрещает использование трюка следующим образом для принудительного вывода шаблона следующим образом:

template <typename ...Ts,
          typename A,
          typename B,
          std::enable_if_t<sizeof...(Ts) == 0, int> = 0> // Ill-formed NDR :-(
Pair<std::decay_t<A>, std::decay_t<B>> MakePair(A&&a, B&& b)
{
    return {a, b};
}

Примечание: я знаю, что правило вывода C ++ 17 делает make_* устаревшим.

1 Ответ

0 голосов
/ 30 ноября 2018

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

template<class...Ts>
union U : Ts... {}; // unions can't have base classes

template<class...Ts>
class C : Ts..., Ts... {}; // classes can't have duplicate direct base classes

template<class...Ts>
void f() {
    // sizeof(void) is invalid, but it can vanish
    int x[] = {(sizeof(void) + sizeof(Ts))..., 0};
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...