Подтвердить что ты не робот

Является ли этот синтаксис шаблона незаконным?

Я получаю "внутреннюю ошибку компилятора" с помощью GCC 4.9.2:

#include <type_traits>

template <typename T, typename, int, template <typename U, U, U> class>
struct Sort;

template <typename T, template <T...> class Z, T N, T... Is,
          template <typename U, U, U> class Comparator>
struct Sort<T, Z<N, Is...>, 0, Comparator> {
  template <T I>
  struct less_than : std::integral_constant<bool, Comparator<T, I, N>::value> {
  };
};

int main() {}

В сообщении об ошибке указано:

c:\ADandD > g++ -std = С++ 14 ComparatorAndSorterTGeneralized.cpp ComparatorAndSorterTGeneralized.cpp: 254: 80: внутренняя ошибка компилятора: в tsubst, при cp/pt.c: 11738

template<T I>
struct less_than : std::integral_constant<bool, Comparator<T,I,N>::value> {};
                                                                              ^

Пожалуйста, отправьте полный отчет об ошибке, с предварительно обработанным источником, если это необходимо. Для получения инструкций см. http://gcc.gnu.org/bugs.html.

Проблема заключается в использовании шаблона <typename U, U, U> class Comparator. Я никогда не пробовал это раньше. Сначала я попробовал шаблон <typename T, T, T> class Comparator, но это не скомпилировалось из-за затенения шаблона, поэтому я знал, что это незаконно. И затем смена его на U все еще не скомпилировалась, поэтому я думал, что вся идея не допускается.

Обновление: при создании экземпляра это компилируется в Visual Studio 2015 Preview:

#include <type_traits>

template <typename T, typename, int, template <typename U, U, U> class>
struct Sort;

template <typename T, template <T...> class Z, T N, T... Is,
          template <typename U, U, U> class Comparator>
struct Sort<T, Z<N, Is...>, 0, Comparator> {
  template <T I>
  struct less_than : std::integral_constant<bool, Comparator<T, I, N>::value> {
  };
};

template <int...>
struct index_sequence {};

template <typename T, T A, T B>
    struct LessThan : std::integral_constant < bool,
    A<B> {};

enum { QuickSort, MergeSort, InsertionSort };

int main() {
  Sort<int, index_sequence<4, 5, 6, 1, 2, 7>, QuickSort, LessThan> quickSort;
}
4b9b3361

Ответ 1

template <typename T, typename, int, template <typename U, U, U> class>
  struct Sort;  

Это совершенно законно.

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

template <typename T, typename T2, int I, template <typename U, U X, U Y> class TT>
  struct Sort;  

Он объявляет шаблон класса Sort, который имеет четыре параметра шаблона, параметр типа T, второй тип T2 (не обозначенный в оригинале), параметр шаблона I, не являющийся типом, и параметр шаблона шаблона TT.

Параметр шаблона шаблона TT должен иметь шаблон шаблона с тремя параметрами шаблона, U - это параметр типа, а второй и третий (X и Y) - это непиковые шаблонные параметры типа U.

Подходящим аргументом для четвертого параметра шаблона Sort может быть что-то вроде:

template <typename T, T t1, T t2>
  class Foo
  { static const bool value = t1 < t2; };

который будет создан таким образом:

Foo<int, 1, 2> fi;

или

Foo<char, 'a', 'b'> fc;