template<class T>
struct A {};
template<class T>
struct B {
using type=T;
};
template<class T>
struct A<typename B<T>::type> {};
это в основном то же самое, но с одним меньшим количеством шаблонов.
Это тоже не работает.
Проблема в том, что B<T>::type
или B<T>::template Z
или что-то еще, в общем случае, является произвольной функцией времени компиляции.
И чтобы сопоставить шаблон с ним, нам нужно инвертировать эту произвольную функцию времени компиляции.
Стандарт гласит: «Компиляторы не должны этого делать», что является одной из немногих вменяемых вещей, которые вы можете сделать здесь. Это определенно говорит это для типов; Что касается шаблонов, то в стандартной формулировке параметров шаблонов часто отсутствуют детали, поэтому я не удивлюсь, если эта формулировка будет отсутствовать. Но если этого не произойдет, это будет ошибка в стандарте.
Чтобы перейти с
template<class T>
struct A<typename B<T>::type> {};
, чтобы увидеть, соответствует ли A<foo>
, необходимо проверить все типы T
, чтобы увидеть, какой из них имеет B<T>::type
, равный foo
.
Возможно, это не то, что вы намереваетесь попросить, но это то, о чем вы просите.
То же самое относится и к вашему примеру шаблона.
template <template <typename> class F>
struct A<B<F>::template C> {
static int foo();
};
вы просите, чтобы компилятор проверил каждый тип F
, так что если вы передадите его произвольному шаблону B<>
, а затем оцените ::C
, соответствует ли шаблон тому, что вы передаете A
.
Первый забавный кейс:
template<class X>
struct C0 {};
template <template <typename> class F>
struct B {
template <typename T>
using C=C0<X>:
};
Теперь, что такое F
в A<C0>
? Каждый F
квалифицируется.
template<class X>
struct C0 {};
template <template <typename> class F, class=void>
struct B {
template <typename T>
using C=C0<X>:
};
template<class X>
struct C1 {};
template <template <typename> class F, class=void>
struct B<
F,
std::enable_if_t<
proves_collatz_conjecture( F<int>::value )
>
> {
template <typename T>
using C=C1<T>;
};
теперь для паттерна mach A<C0>
компилятор должен создать F
таким образом, чтобы F<int>::value
был типом времени компиляции, который при передаче в proves_collatz_conjecture
возвращает true
во время компиляции.
Это было бы полезно.
специализация шаблона - сопоставление с шаблоном. В C ++ вы не можете сопоставлять шаблоны с зависимыми типами (и, вероятно, с шаблонами), поскольку ни у типов, ни у шаблонов нет идентификатора, превышающего их значение.
Вы не можете проверить область, в которой определена переменная, тип или шаблон. Поэтому вы не можете сопоставить шаблон с этим.
Если вы хотите делать то, что хотите, шаблон C
должен иметь свойство, которое вы можете проверить и проверить.