не является ли пакет параметров без типа, который считается недействительным, незаконным?

gcc-4.8 принимает этот код, но разве это не неправильно, поскольку пакет параметров без типа эквивалентен void..., что является недопустимым?

template <typename T,
          typename std::enable_if<std::is_integral<T>::value>::type...>
void test(T) {}

Я пробовал это с clang-3.5, который тоже принимает это. Это ошибка компилятора или я что-то не понимаю?


Полный тестовый код ниже, в котором используются пустые пакеты параметров без типа для упрощения enable_if. Это почти то же самое, что и в Remastered enable_if Flaming Dangerzone, за исключением того, что после замены пакет становится void....

#include <type_traits>

template < typename C >
using enable_if_t = typename std::enable_if<C::value>::type ;

template < typename T, enable_if_t<std::is_integral<T>>... >
void test(T){} // #1

template < typename T, enable_if_t<std::is_floating_point<T>>... >
void test(T){} //#2

int main()
{
   test(0);   // calls #1
   test(0.0); // calls #2
   return 0;
}

gcc-4.8 отлично компилирует приведенный выше код. clang не работает, но это потому, что у него другая ошибка http://llvm.org/bugs/show_bug.cgi?id=11723.


person Hui    schedule 01.05.2014    source источник
comment
Я считаю это незаконным. См. Параграф [temp.param] 14.1 / 7 стандарта: параметр шаблона, не являющийся типом, не должен объявляться как имеющий тип с плавающей запятой, класс или тип void.   -  person Constructor    schedule 01.05.2014
comment
Вы должны предоставить автономный код. Все, что я могу сказать, это то, что ваш код не компилируется из-за отсутствия include и main.   -  person Johannes Schaub - litb    schedule 01.05.2014
comment
@ JohannesSchaub-litb См. простой пример, воспроизводящий проблему.   -  person Constructor    schedule 01.05.2014
comment
@Constructor Похоже, что он не проверяется, если не используется: coliru.stacked-crooked.com/a/ e60e1c9a202d3e0f   -  person dyp    schedule 01.05.2014
comment
@dyp Это интересно. Что вы думаете об этом? Законно ли такое поведение?   -  person Constructor    schedule 01.05.2014
comment
@dyp у вас есть еще одна ошибка, потому что вы передаете тип параметру, не являющемуся типом (void() - это тип функции).   -  person Johannes Schaub - litb    schedule 01.05.2014
comment
@ JohannesSchaub-litb Верно, я не уверен, как это интерпретируется в этом контексте (приведение к функциональной нотации или тип). В любом случае, я думаю, что это показывает, что есть проверка, когда используется пакет параметров (не пустой). Таким образом, вопрос может заключаться в том, являются ли пустые пакеты параметров, не относящиеся к типу, допустимыми для типа void?   -  person dyp    schedule 01.05.2014
comment
@dyp, что на практике не имеет значения, потому что даже если бы они были, правило, если для всех допустимых специализаций требуется пустой пакет параметров шаблона, определение шаблона неверно сформировано, NDR будет применяться (и хотя, похоже, будут непреднамеренные отклонения на основе это правило, например такие утверждения, как require_empty_pack<T...>();, я думаю, что отказ от кода вопросов на основе этого правила был бы преднамеренным, поскольку это облегчает работу компилятору).   -  person Johannes Schaub - litb    schedule 01.05.2014
comment
(Я должен ослабить мое утверждение, которое на практике не имеет значения, потому что вопрос в коде имеет T быть переменной, поэтому test действительно может быть создан и для непустых пакетов, поэтому правило не будет применяться к этому конкретному коду ..)   -  person Johannes Schaub - litb    schedule 01.05.2014
comment
Я добавил настоящий тестовый код и объяснил, как можно использовать такие пустые пакеты.   -  person Hui    schedule 02.05.2014
comment
Думаю, с кодом все в порядке.   -  person BЈовић    schedule 02.05.2014
comment
Я не вижу нигде в этом коде, где вы создаете экземпляр test с входными данными, что приводит к void....   -  person Lightness Races in Orbit    schedule 02.05.2014
comment
void... не создается, но является результатом подстановки.   -  person Hui    schedule 03.05.2014
comment
похоже на template<int N> void f(char[n]) { }. некоторые компиляторы также не отклоняют f<0>(), потому что они немедленно преобразуют char[N] в char*, и тогда не остается N для замены. В вашем случае нет шаблона, который можно было бы заменить.   -  person Johannes Schaub - litb    schedule 06.05.2014
comment
Верно, но законно ли это по стандарту?   -  person Hui    schedule 08.05.2014


Ответы (1)


После долгих поисков в контексте другого вопроса, я нашел в стандарте небольшой фрагмент, в котором четко указано, что это незаконно:

[temp.res] /8.3:

Программа плохо сформирована, диагностика не требуется, если: ... для каждой допустимой специализации вариативного шаблона требуется пустой пакет параметров шаблона.

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

person zennehoy    schedule 12.08.2018