Возьмите следующий фрагмент кода:
struct whatever {};
template < template <typename, typename> class FOX, typename bat>
struct wulf {};
template <typename A, typename B, typename C = whatever>
struct box;
template <typename A, typename B>
struct box<A, B, whatever> {};
template <typename A, typename B, typename C>
struct box : wulf<box, C> {};
int main(void)
{
return 0;
}
Он прекрасно компилируется под gcc 4.1.2, но выдает следующую ошибку при компиляции под gcc 4.7.2:
main.cpp:14:25 error: type/value mismatch at argument 1 in template parameter list for 'template<template<class,class> class FOX, class bat> struct wulf'
main.cpp:14:25 error: expected a template of type 'template<class, class> FOX', got 'template<class A, class B, class C> struct box'
Это наименьший пример кода, с помощью которого я могу воспроизвести эту ошибку, и я не знаю, что происходит. Почему код отклоняется и есть ли правильный способ сделать это, который будет компилироваться в обоих?
Ваш wulf
В качестве первого аргумента шаблона шаблона шаблон класса принимает шаблон класса, который принимает два параметра типа.
Здесь вы пытаетесь предоставить в качестве соответствующего аргумента шаблон класса (box
) что занимает три параметры типа:
template <typename A, typename B, typename C>
struct box : wulf<box, C> {};
// ^^^
Это незаконно. Неважно, задан ли тип аргумента по умолчанию для параметра третьего типа box
Шаблон класса: тип и количество аргументов шаблона должны точно совпадать.
Чтобы решить проблему, измените определение вашего wulf
Шаблон класса выглядит следующим образом:
template < template <typename, typename, typename> class FOX, typename bat>
// ^^^^^^^^
struct wulf {};
Вот живой пример это показывает, что ваш код компилируется с помощью вышеуказанного исправления.
Используя C ++ 11, вы можете решить проблему, изменив wulf
чтобы:
template < template <typename...> class FOX, typename bat>
struct wulf {};
хотя GCC 4.1 не примет это, я боюсь …
Еще один трюк, который я иногда использую: Добавить класс-обёртку для box
:
struct whatever {};
template < template <typename,typename> class FOX, typename bat>
struct wulf {};
template <typename A, typename B, typename C = whatever>
struct box;
template <typename A, typename B>
struct box<A, B, whatever> {};
template <typename A, typename B>
struct box2 : box<A, B> {};
template <typename A, typename B, typename C>
struct box : wulf<box2, C> {};
int main(void)
{
return 0;
}
Я не знаю, если это (потерять третий аргумент для box
в wulf
) является проблемой в вашем случае, но в прошлом у меня было несколько вариантов использования, где этот метод помог.