Normally you can partially specialize a template class against an instantiated template class. For instance
template<class T>
struct specialize_me {};
template<class T>
struct specialize_me<std::vector<T>> {
static const int foo = 3;
};
the template class specialize_me
is partially specialized against the instantiated template class std::vector<T>
. This specialization is selected when specialize_me
is instantiated with std::vector<T>
, for any class T
.
int main() {
std::cout << specialize_me<std::vector<int>>::foo; // Compiles.
}
However, I cannot figure out how to specialize a template template class against an instantiated nested template class:
// Nested template class.
template<class T>
struct Either {
template<class U>
struct Or {};
};
template<template<class> class T>
struct specialize_me_2 {};
template<class T>
struct specialize_me_2<Either<T>::template Or> {
static const int foo = 3;
};
In this case, the specialization is not selected when I instantiate specialize_me_2
with the class Either<T>::template Or
for any class T
. My guess is that this happens because the compiler would have to confirm or deny, "There exists a T
such that Either<T>::template Or
is the same type as the specialize_me_2
instantiation" in order to select my specialization, and it is not programmed nor specified to do so.
int main() {
std::cout << specialize_me_2<Either<int>::Or>::foo; // Does not compile. 'foo' is not a member of specialize_me_2<Either<int>::Or>.
}
Is there a way to specialize specialize_me_2
such that the specialization is selected whenever specialize_me_2
is instantiated with Either<T>::Or
for any T
?
This Either
struct is eventually going to represent an error-carrying type, so Either<T>
denotes that T
is the error type, and Either<T>::Or<U>
denotes that U
is the type being carried by the successful computation.
If this is impossible, I might still be able to use #define
s to enable you to define Either<T>
for each T
as it is needed, where #define
also includes the specialize_me_2
specialization for that particular Either<T>::Or
. Indeed, I intend to use the Either
struct in programs by writing template<class T> using FooError = Either<Foo>::Or<T>
anyway and then write FooError<Bar>
, FooError<Quux>
and so on, so using this wouldn't be a huge break from the intended usage.
Or
supposed to be instantiated with in your second example? - super::
, hence the reason the compiler cannot deduceT
inEither<T>::template Or
. - MicroVirus