简体   繁体   English

C ++ - 模板专业化和部分专业化

[英]C++ - Template Specialization & Partial Specialization

I have been looking all over the internet and stackoverflow for a concrete answer but I can't seem to find one. 我一直在寻找互联网和stackoverflow的具体答案,但我似乎无法找到一个。 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() 1)只有Z的,其中x = 2和y = 2需要有一个公共方法void J()

2) For char Z's of x = 2 and y= 2 J will do something; 2)对于x = 2且y = 2 J的char Z,它会做某事; for everything else it does something else 对于其他一切,它做了别的事

3) For only Z's where T is char will the array be initialized to some value. 3)对于只有Z是char的字符,将数组初始化为某个值。 For everything else it's 0 其他一切都是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: 同样(假设J存在)这不起作用:

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. 我需要在Z中保留所有其他方法。给出一个提示或指向正确的方向(也许我错过了一个问题,因为有很多)会有所帮助。

Thanks. 谢谢。

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. 您似乎只想定义某些特化的某些函数:如果print()char和一般情况之间没有变化,那么您似乎不想重新定义它。

// 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 : 逃避代码重复的唯一方法是使用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 ). 目前你无法做到你想做的事情而没有重复( static if已经提出用于下一个C ++标准,删除代码重复的功能是static if ,请参阅n3322n3329 )。

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 你可以看一下这门课程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. 在此示例中,仅当模板中的类型是指针类型时,才希望在doThingy()中特化行为。 You cannot use overload of method doThingy() in this case. 在这种情况下,您不能使用方法doThingy()的重载。 This is because you cannot overload a function with no arguments. 这是因为您不能重载没有参数的函数。 But you can have partial specialization of the struct helper. 但是你可以对struct helper进行部分特化。 In specialized template, you implemented wished behavior for the doThingy(). 在专用模板中,您实现了doThingy()的所需行为。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM