Comprobación de concepto simple
Digamos que tengo una plantilla simple como esta:
template<typename T>
class A {};
Y quiero especificar que el parámetro de tipo T
es de algún tipo no relacionado X<U>
donde U
no se conoce (o no se puede especificar).
¿Hay alguna manera de expresar eso como un concepto?
2 answers
¿Hay alguna manera de expresar eso como un concepto?
No necesitas un concepto, la especialización de plantillas de clase funciona bien en tu caso.
Como ejemplo, puedes hacer esto:
template<typename T>
class A;
template<typename U>
class A<X<U>> { /* ... */ };
De esta manera, a menos que A
se instancie con un tipo de la forma X<U>
(donde U
es desconocido), obtendrá un error en tiempo de compilación porque la plantilla primaria no está definida. En otros términos, no funcionará para todos los tipos, pero X<U>
(para cada U
), donde este último coincide con la especialización de plantilla de clase que tiene una definición adecuada.
Tenga en cuenta que asumí X
es un tipo conocido. Eso no está claro en tu pregunta.
De todos modos, si no lo es y desea aceptar tipos de la forma X<U>
para cada X
y cada U
, todavía puede hacer esto:
template<typename T>
class A;
template<template<typename> class X, typename U>
class A<X<U>> { /* ... */ };
Como un ejemplo mínimo:
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;
}
Tanto A<S<int>>
como A<S<double>>
están bien y el ejemplo compila. Si cambia el comentario, ya no se compilará para A<char>
isn't definido en absoluto.
Como nota al margen, si no quieres usar la especialización de plantillas de clase y quieres simular conceptos (recuerda que aún no forman parte del estándar y no lo serán al menos hasta 2020), puedes hacer algo como esto:
#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;
}
Es decir, dado un tipo genérico T
, estática afirmar su tipo real por medio de otra estructura (is_xu
en el ejemplo) que verifica si T
es de la forma X<U>
(para cada U
) o ni.
Mis dos centavos: la especialización de plantillas de clase es más fácil de leer y entender de un vistazo.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-06 09:04:32
template <typename T, template <typename> class C>
concept bool Template = requires (T t) { {t} -> C<auto>; };
Ahora se le da una plantilla de clase:
template <typename T>
struct X {};
Un parámetro de plantilla de tipo se puede restringir usando:
template <typename T> requires Template<T, X>
class A {};
O:
template <Template<X> T>
class A {};
DEMO
Esto también funcionará para los tipos derivados de X<U>
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-06 10:41:46