问题
I have been looking all over the internet and stackoverflow for a concrete answer but I can't seem to find one. I have to create a generic class and then implement specific functions. My specific instructions were: You need to make use of Template Expression Parameters and Template Class Specialization and Partial Specialization.
I have a template class:
template <class T, int x, int y>
class Z {
T **array[x][y];
public:
Z();
void print();
//and other methods
};
I need to:
1) Only Z's where x= 2 and y = 2 need to have a public method void J()
2) For char Z's of x = 2 and y= 2 J will do something; for everything else it does something else
3) For only Z's where T is char will the array be initialized to some value. For everything else it's 0
Naturally, this works:
template<class T, int x, int y>
Z<T,x,y>::Z<T,x,y>() { //initialize to 0 }
But this doesn't:
template<int x, int y>
Z<char,x,y>::Z<char,x,y>() { //initialize to something}
And likewise (assume J exists) this does not work:
template <class T>
void Z<T,2,2>::J() { //something }
My question is:
Is there any simple method for implementing the above items? I need to keep all the other methods in Z. Giving a hint or pointing in the right direction (maybe I missed a question since there are a lot) would be helpful.
Thanks.
回答1:
It seems you want to define only some functions of some specializations : if print()
does not change between the char
specialization and the general case, it seems that you don't want to redefine it.
// What you want to do (illegal in C++)
template<int,typename T>
struct Z
{
T myValue;
Z();
void print() { /* ... */ }
};
template<int i, typename T>
Z<i,T>::Z() { /* ... */ }
template<int i>
Z<i,char>::Z() { /* ... */ }
However, it does not work like this. Partial or full specializations of class have almost nothing in common, except 'prototype' of template parameters:
// The two following types have only two things related: the template parameter is an int,
// and the second type is a full specialization of the first. There are no relations between
// the content of these 2 types.
template<int> struct A {};
template<> struct A<42> { void work(); };
You have to declare and define each (partial) specialization:
// Fixed example
template<int,typename T>
struct Z
{
T myValue;
Z();
void print() { /* ... */ }
};
template<int i, typename T>
Z<i,T>::Z() { /* ... */ }
// Specialization for <all-ints,char>
template<int i>
struct Z<i,char>
{
char myValue;
char othervalue;
Z();
void print() { /* Same code than for the general case */ }
};
template<int i>
Z<i,char>::Z() { /* ... */ }
The only way to escape the code duplication is by using inheritance of traits:
// Example with the print function
template<typename T>
struct print_helper
{
void print() { /* ... */ }
};
// Fixed example
template<int,typename T>
struct Z : public print_helper<T>
{
T myValue;
Z();
};
template<int i, typename T>
Z<i,T>::Z() { /* ... */ }
// Specialization for <all-ints,char>
template<int i>
struct Z<i,char> : public print_helper<char>
{
char myValue;
char othervalue;
Z();
};
template<int i>
Z<i,char>::Z() { /* ... */ }
You cannot do what you want without duplication for the moment (the feature removing code duplication is static if
and has been proposed for the next C++ standard, see n3322 and n3329).
回答2:
You may have a look at this course http://channel9.msdn.com/Series/C9-Lectures-Stephan-T-Lavavej-Core-C-/Stephan-T-Lavavej-Core-C-5-of-n
While this is not possible that you define partial specialization for function templates, you can define partial specialization for class or struct template.
template<typename T> struct helper {
static void doThingy(){}
};
template<typename X> struct helper<X*> {
static void doThingy(){}
};
Helper(double*)::doThingy();
In this example, you want to specialize behavior in doThingy() only when the type in template is a pointer type. You cannot use overload of method doThingy() in this case. This is because you cannot overload a function with no arguments. But you can have partial specialization of the struct helper. In specialized template, you implemented wished behavior for the doThingy().
来源:https://stackoverflow.com/questions/13444615/c-template-specialization-partial-specialization