C++ 派生类的部分类模板专门化

C++ 派生类的部分类模板专门化,c++,template-specialization,C++,Template Specialization,我正试图为嵌入式Linux系统编写一个在LCD上绘制用户界面元素的程序。我有一个名为Widget的基类,它实现了绘图和擦除等基本功能,并具有x/y位置和宽度/高度等属性。然后,我使用派生类Label、Button和ProgressBar,它们分别添加自己的属性(文本、焦点和值) 我的问题是,我想创建一个名为WidgetArray的模板容器类,它将自动生成一个小部件网格,并批量编辑它们的属性。但是,例如,如果widgetary包含一个函数,该函数接受字符串向量并将每个字符串分配给标签的text属性

我正试图为嵌入式Linux系统编写一个在LCD上绘制用户界面元素的程序。我有一个名为
Widget
的基类,它实现了绘图和擦除等基本功能,并具有x/y位置和宽度/高度等属性。然后,我使用派生类
Label
Button
ProgressBar
,它们分别添加自己的属性(文本、焦点和值)

我的问题是,我想创建一个名为
WidgetArray
的模板容器类,它将自动生成一个小部件网格,并批量编辑它们的属性。但是,例如,如果
widgetary
包含一个函数,该函数接受字符串向量并将每个字符串分配给
标签的
text
属性,如果我声明了
widgetary
的一个实例,其中包含
ProgressBar
s(没有文本属性),编译器会抱怨。这似乎是模板专门化的完美案例。我正在阅读关于模板专业化的页面,看到了以下内容:

当我们为一个模板类声明专门化时,我们还必须定义它的所有成员,甚至那些完全等于泛型模板类的成员,因为从泛型模板到专门化没有成员的“继承”

请告诉我有办法解决这个问题。
WidgetArray
的绝大多数成员函数对于
Widget
的所有派生类都是完全有效的,而且我不得不复制并粘贴
WidgetArray
的整个代码,只是为了为派生类添加一个专门的函数,这似乎非常愚蠢

下面是我的代码的简化版本:

template<class T>
class WidgetArray {
protected:
    std::vector<T> children;
    int columns, x, y;
    int element_w, element_h;
    int x_padding, y_padding; 
public:
    WidgetArray() {
        columns = 1;
        children.resize(1);
        x = 0;
        y = 0;
    }
    WidgetArray(int x_in, int y_in, int size, int cols) {
        unsigned int counter1=0, counter2=0;
        columns = cols;
        x = x_in;
        y = y_in;
        element_w = 10;
        element_h = 10;
        x_padding = 0;
        y_padding = 0;
        children.resize(size);
        for (unsigned ii = 0; ii < size; ii++) {
            if (counter1 > columns) {
                counter1 = 0; //column number
                counter2++; //row number
            }
            children.at(ii).x = counter1*(element_w + x_padding) + x;
            children.at(ii).y = counter2*(element_h + y_padding) + y;
            children.at(ii).width = element_w;
            children.at(ii).height = element_h;
        }
    }        
    void draw_children(std::vector<unsigned char>& cmd_str){
        for (unsigned ii=0; ii < children.size(); ii++) children.at(ii).draw(cmd_str);
    }
    void redraw_children(std::vector<unsigned char>& cmd_str) {
        for (unsigned ii=0; ii < children.size(); ii++) {
            children.at(ii).erase(cmd_str);
            children.at(ii).draw(cmd_str);
        }
    }
    void erase_children(std::vector<unsigned char>& cmd_str) {
        for (unsigned ii=0; ii < children.size(); ii++) children.at(ii).erase(cmd_str);
    }
    int reform(int num_elements, int cols, int x_in, int y_in) {
        unsigned int counter1=0, counter2=0;

        children.clear();
        children.resize(num_elements);
        columns = cols;
        x = x_in;
        y = y_in;
        for (unsigned ii = 0; ii < children.size(); ii++) {
            if (counter1 > columns) {
                counter1 = 0; //column number
                counter2++; //row number
            }
            children.at(ii).x = counter1*(element_w + x_padding) + x;
            children.at(ii).y = counter2*(element_h + y_padding) + y;
            children.at(ii).width = element_w;
            children.at(ii).height = element_h;
        }
        return 1;
    }
    int assign_text(std::vector<string> text) {
        for (unsigned ii=0; ii<children.size() || ii < text.size(); ii++) {
            //This is only valid if my type is a Button or Label but I want
            //the rest of the code for WidgetArray to be valid for any derived
            //class of Widget
            children.at(ii).text = text.at(ii);
        }
    }
};
模板
类WidgetArray{
受保护的:
性病媒儿童;
int列,x,y;
int元素w,元素h;
int x_填充,y_填充;
公众:
WidgetArray(){
列=1;
调整大小(1);
x=0;
y=0;
}
WidgetArray(整数x_英寸,整数y_英寸,整数大小,整数列){
无符号整数计数器1=0,计数器2=0;
列=列;
x=x_英寸;
y=y_英寸;
元素w=10;
元素h=10;
x_=0;
y_=0;
调整大小(大小);
用于(无符号ii=0;ii列){
计数器1=0;//列号
计数器2++;//行号
}
在(ii)处,x=counter1*(元素w+x+x);
在(ii)处,y=counter2*(元素h+y+y);
子元素。在(ii)处。宽度=元素w;
儿童。在(ii)处。身高=元素_h;
}
}        
void draw_children(std::vector和cmd_str){
对于(无符号ii=0;ii列){
计数器1=0;//列号
计数器2++;//行号
}
在(ii)处,x=counter1*(元素w+x+x);
在(ii)处,y=counter2*(元素h+y+y);
子元素。在(ii)处。宽度=元素w;
儿童。在(ii)处。身高=元素_h;
}
返回1;
}
int赋值_文本(标准::向量文本){

对于(unsigned ii=0;ii,听起来您想要的只是一个模板基类,它包含所有特定于这两种方法的方法,然后从中继承。例如:

template <typename T>
struct base
{
protected:
    std::vector<T> children;
    ~base() { }

public:
    void draw_children();
    //Other methods common to all template parameters T

};


class WidgetArrayString
    : public base<std::string>
{
    //Methods specific only to strings
};

class WidgetArrayProgressBar
    : public base<ProgressBar>
{
    //Methods specific only to progress bar
};
模板
结构基
{
受保护的:
性病媒儿童;
~base(){}
公众:
void draw_children();
//所有模板参数T通用的其他方法
};
类WidgetArrayString
:公共基地
{
//仅特定于字符串的方法
};
类WidgetArrayProgressBar
:公共基地
{
//仅特定于进度条的方法
};

我试图理解为什么您首先要专门化您正在描述的案例。添加的小部件必须符合WidgetArray处理它们的方式。除此之外的任何内容都可以在派生中扩展,即
类ProgressBarArray:public WidgetArray
,并将进度条的方法添加到那门课;不是专业化?还是我完全误解了问题和最终目标?换句话说,我不确定你为什么认为专业化是正确的答案?好吧,现在我觉得自己很傻。那会有用的。我想我只是在脑子里想,既然我在使用模板,那一定是解决方案。谢谢,我没意识到你可以用它Beezum如果是这样的话,那么你真的应该烤你的面条了。