I have put together an example on creating a base template with a number of specializations.
#include <iostream>
template<typename T, typename U = void>
struct foo {
static void apply() {
std::cout << "a: " << __FUNCTION__ << std::endl;
}
};
template<typename U>
struct foo<int, U> {
static void apply() {
std::cout << "b: " << __FUNCTION__ << std::endl;
}
};
template<typename U>
struct foo<double, U> {
static void apply() {
std::cout << "c: " << __FUNCTION__ << std::endl;
}
};
template<>
struct foo<double, double> {
static void apply() {
std::cout << "d: " << __FUNCTION__ << std::endl;
}
};
template<typename T>
struct foo<T, std::enable_if_t<std::is_same_v<T, char>>> {
static void apply() {
std::cout << "e: " << __FUNCTION__ << std::endl;
}
};
template<>
struct foo<short> {
static void apply() {
std::cout << "f: " << __FUNCTION__ << std::endl;
}
};
template<>
struct foo<unsigned long, void> {
static void apply() {
std::cout << "g: " << __FUNCTION__ << std::endl;
}
};
int main() {
foo<long>::apply();
foo<long, long>::apply();
foo<int>::apply();
foo<int, int>::apply();
foo<double>::apply();
foo<double, float>::apply();
foo<double, double>::apply();
foo<char>::apply();
foo<short>::apply();
foo<unsigned long>::apply();
return 0;
}
When a specialization is defined and a template parameter is defined in the base template such as the template parameter U which is defaulted to void how is this propagated to the specializations. Is the done at the point of specialization as in the first specialization foo<int, U> and U must be void as it is unspecified and adopted from the base template?
Also with the
template<typename T>
struct foo<T, std::enable_if_t<std::is_same_v<T, char>>>
specialization, the enable_if_t yields the type void, why does this not collide with the base template and how is it considered more specialized?
Any additional quotes from the standard to complement answers are additionally welcome.