【问题标题】:Return Generic Type data from function从函数返回通用类型数据
【发布时间】:2013-04-25 11:42:35
【问题描述】:

我已经编写了以下代码。其中函数func()打印头部和数据。

class ICell
{
    public:
        wstring header;
        virtual void Fetch() = 0;
};

template <class T>
class Cell : public ICell
{
public:
    //wstring header;
    T data;
    void Fetch()
    {
        wcout<< header << L": ";
        cout<<data<<endl;
    }
  // implementation of cell methods
};

class Row
{
public:
  vector <ICell *> cells;
};

有没有办法在函数内返回数据而不是打印?如果是这样,应该修改代码的哪一部分? 提前致谢。

int main()
{
    Cell<int>c1;
    Cell<double>c2;

    c1.header = L"Roll", c1.data = 100;
    c2.header = L"CGPA", c2.data = 3.5;

    Row r;
    r.cells.push_back(&c1);
    r.cells.push_back(&c2);

    vector <ICell *>::iterator it;
    for(it=r.cells.begin();it!=r.cells.end();it++)
    {
        //checkt type of it wherther it points Cell<int> or Cell<double>
    }

    return 0;
}

我在这里改变了我的问题。在循环内的 main() 中,如何检查 'it' 指向的对象类型?

感谢大家的耐心和帮助:)

【问题讨论】:

  • void Fetch(); 更改为T Fetch();
  • 你可以返回一个你正在输出的数据字符串,也许?
  • @AlokSave:如果Theader 都作为一个单元返回,则不会...
  • @AlokSave 基类不知道数据类型是什么。他需要的是 CRTP,但它不适用于虚拟功能。根本没有出路。
  • 我怀疑这里有一个 XY 问题...

标签: c++ function generics return virtual


【解决方案1】:

最简单的方法是使用dynamic_cast:

vector <ICell *>::iterator it;
for(it=r.cells.begin();it!=r.cells.end();it++)
{
    Cell<int>* cell_i= dynamic_cast<Cell<int>*>(*it);
    if(cell_i)
    {
       do_something(cell_i->data);
       continue;
    }

    Cell<double>* cell_d= dynamic_cast<Cell<double>*>(*it);
    if(cell_d)
    {
       do_something(cell_d->data);
       continue;
    } 
}

更好的方法是使用访问者模式:

class ICellVisitor; //declaration for ICell to understand ICell* pointer
class ICell
{   public:
    ~ICell(){}; // important
    std::wstring header;
    virtual void visit( ICellVisitor* v ) = 0;
};
template <class T> class Cell; // for Cell<T>* pointer
class ICellVisitor
{   public:
    virtual void visit( Cell<int>* c ) = 0;
    virtual void visit( Cell<double>* c ) = 0;
    virtual void visit( Cell<float>* c ) = 0;
    virtual void visit( Cell<long long>* c ) = 0;
};
template <class T> class Cell : public ICell
{   public:
    //wstring header;
    T data;
    void visit( ICellVisitor* v )
    {
        std::wcout<< header << L": ";
        v->visit(this);
    }
  // implementation of cell methods
};
class Row
{ public:
  std::vector <ICell *> cells;
};

现在我们需要定义具体的访问者来保留每种类型的算法:

class MyCellVisitor: public ICellVisitor
{   public:
    void visit( Cell<int>* c ){ 
        std::wcout<<"(int)"<<c->data<<std::endl; 
    }
    void visit( Cell<double>* c ){ 
        std::wcout<<"(double)"<<c->data<<std::endl;
    }
    void visit( Cell<float>* c ){ 
        std::wcout<<"(float)"<<c->data<<std::endl;
    }
    void visit( Cell<long long>* c ){ 
        std::wcout<<"(long long)"<<c->data<<std::endl;
    }
};

int main()
{
    Cell<int>c1;
    Cell<double>c2;
    c1.header = L"Roll", c1.data = 100;
    c2.header = L"CGPA", c2.data = 3.5;
    Row r;
    r.cells.push_back(&c1);
    r.cells.push_back(&c2);
    MyCellVisitor visitor;
    std::vector <ICell *>::iterator it;
    for(it=r.cells.begin();it!=r.cells.end();it++)
    {
        (*it)->visit( &visitor );
    }
    return 0;
}

【讨论】:

    猜你喜欢
    • 2019-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多