Ответ 1
Есть ли способ выразить это как концепцию?
Вам не нужна концепция, специализация шаблонов классов работает отлично в вашем случае.
В качестве примера вы можете сделать это:
template<typename T>
class A;
template<typename U>
class A<X<U>> { /* ... */ };
Таким образом, если A
не создается с типом формы X<U>
(где U
неизвестно), вы получите ошибку времени компиляции, потому что основной шаблон не определен. Другими словами, он не будет работать для всех типов, но X<U>
(для каждого U
), где последний соответствует специализации шаблона класса, которая имеет правильное определение.
Обратите внимание, что я предположил, что X
является известным типом. Это не ясно из вашего вопроса.
В любом случае, если это не так, и вы хотите принять типы формы X<U>
для каждого X
и каждого U
, вы все равно можете сделать это:
template<typename T>
class A;
template<template<typename> class X, typename U>
class A<X<U>> { /* ... */ };
Как минимальный рабочий пример:
template<typename>
struct S {};
template<typename>
class A;
template<typename U>
class A<S<U>> {};
int main() {
A<S<int>> aSInt;
A<S<double>> aSDouble;
// A<char> aChar;
}
Оба A<S<int>>
и A<S<double>>
являются точными, и пример компилируется. Если вы переключите комментарий, он больше не будет компилироваться для A<char>
вообще не определен.
В качестве побочного примечания, если вы не хотите использовать специализацию шаблона класса, и хотите имитировать концепции (помните, что они еще не являются частью стандарта, и они не будут, по крайней мере, до 2020 года), вы можете сделайте что-нибудь вроде этого:
#include<type_traits>
template<typename>
struct X {};
template<typename>
struct is_xu: std::false_type {};
template<typename U>
struct is_xu<X<U>>: std::true_type {};
template<typename T>
struct A {
static_assert(is_xu<T>::value, "!");
// ...
};
int main() {
A<X<int>> aXInt;
A<X<double>> aXDouble;
// A<char> aChar;
}
То есть, если задан общий тип T
, static утверждает его фактический тип с помощью другой структуры (is_xu
в примере), которая проверяет, имеет ли T
форму X<U>
(для каждого U
) или нет.
Мои два цента: специализация шаблона класса легче читать и понимать с первого взгляда.