O_o
You can't directly specialize a nested template without specializing the enclosing class. (There are, believe it or not, perfectly logical reasons for this.)
You can do a lot of things to still specialize a nested template of a template class.
You can specialize the enclosing template. (Useless.)
You can simply overload the nested template if it is a template function. (Perfect if it works with the design.)
You can forward the target mechanism to a template that can be specialized normally. (Perfect if accessed through `typedef' or pointer.)
You can forward the implementation by indirection through expanded template parameters of the enclosing template. (Impossible complex.)
You can forward the implementation by interface, with default implementation, to a template that can be specialized normally. (Perfect if the behavior requires partial specialization.)
Soma
Code:
#include <iostream>
#include <typeinfo>
template
<
typename T
>
struct interface;
template
<
typename R
, typename S
, typename T
>
struct implementation
{
typedef R return_type;
typedef S parameter_type;
static R to(interface<T> &, parameter_type &);
};
template
<
typename T
>
struct interface
{
template
<
typename R
>
typename implementation<R, int, T>::return_type to
(
int index
)
{
return(implementation<R, int, T>::to(*this, index));
}
};
template
<
typename R
, typename T
>
struct implementation<R, int, T>
{
private:
template <typename RR, typename RS, typename RT> class THIS_VERSION_HAS_NOT_BEEN_PROVIDED;
private:
public:
typedef THIS_VERSION_HAS_NOT_BEEN_PROVIDED<R, int, T> return_type;
public:
};
template
<
typename T
>
struct implementation<int, int, T>
{
typedef int return_type;
typedef int parameter_type;
static return_type to(interface<T> &, parameter_type index)
{
std::cout << "doing something with " << typeid(return_type).name() << ", " << typeid(parameter_type).name() << ", and " << typeid(T).name() << '\n';
return(return_type());
}
};
template
<
typename T
>
struct implementation<bool, int, T>
{
typedef bool return_type;
typedef int parameter_type;
static return_type to(interface<T> &, parameter_type index)
{
std::cout << "doing something with " << typeid(return_type).name() << ", " << typeid(parameter_type).name() << ", and " << typeid(T).name() << '\n';
return(return_type());
}
};
template
<
typename T
>
struct implementation<char *, int, T>
{
typedef char * return_type;
typedef int parameter_type;
static return_type to(interface<T> &, parameter_type index)
{
std::cout << "doing something with " << typeid(return_type).name() << ", " << typeid(parameter_type).name() << ", and " << typeid(T).name() << '\n';
return(return_type());
}
};
int main()
{
interface<int> test1;
interface<double> test2;
test1.to<int>(1);
test1.to<bool>(2);
test1.to<char *>(3);
test2.to<int>(1);
test2.to<bool>(2);
test2.to<char *>(3);
return(0);
}