Будьте предупреждены: этот вопрос кажется более очевидным, чем на самом деле.
Я хотел бы написать шаблон, который может принимать любой конкретный класс или класс шаблона в качестве параметра шаблона. Это может показаться бесполезным, потому что, не зная, является ли переданный в T шаблонным или нет, вы не будете знать, как его использовать. Причина, по которой я этого хочу, заключается в том, что я могу объявить общий шаблон без определения, чтобы пользователи затем специализировались. Поскольку пользователи специализируются на этом, они всегда знают о типе, с которым имеют дело. Но пользователи не могут специализировать шаблон без его предварительного объявления.
Вы можете сделать это:
template<class T>
class myclass;
Но это не сработает, если вы передадите шаблонный T, например, myclass<std::vector>
не сработает. Итак, мы попробуем это:
template<class T>
class myclass;
template<template<class> T>
class myclass;
Это может быть правильный путь, но он не будет работать как есть, потому что шаблоны классов не могут быть перегружены. Итак, давайте переключим его на шаблоны функций, которые могут быть:
template<class T>
void myfunc();
template<template<class> T>
void myfunc();
Сладкий, значит, мы все сделали правильно? Что ж, может быть разное количество параметров, заданных параметру шаблона шаблона, поэтому мы должны принять это во внимание также.
template<class T>
void myfunc();
template<template<class> T>
void myfunc();
template<template<class, class> T>
void myfunc();
template<template<class, class, class> T>
void myfunc();
// etc.
Ужасно, но библиотека препроцессора Boost может сгенерировать этот код для нас (и в C ++ 0x будет добавлена поддержка шаблонов с переменными значениями, так что это уродство только временно). Но мы все еще забыли случай! Что если один из параметров T не является классом, а является постоянным целым числом? Давайте попробуем поддержать это:
template<class T>
void myfunc();
template<template<class> T>
void myfunc();
template<template<class, class> T>
void myfunc();
template<template<class, class, class> T>
void myfunc();
// etc.
template<template<class> T>
void myfunc();
template<template<class, int> T>
void myfunc();
template<template<int, class> T>
void myfunc();
template<template<int, class, class> T>
void myfunc();
template<template<class, int, class> T>
void myfunc();
template<template<class, class, int> T>
void myfunc();
// etc.
Э-э-э Учитывая, что любой тип константы может быть передан в шаблон, в любом количестве, смешанный с параметрами класса, комбинаторный взрыв KABLOOEY. Просто, чтобы сделать вещи более сложными, что, если любой из параметров Т сами по себе являются шаблонами?