包含类模板任何特化的C ++变量

时间:2016-04-25 16:28:54

标签: c++ templates template-meta-programming template-specialization

我需要能够在变量中存储模板的任何特化,例如:

template<T>
class Grid {
  int GetRows();
  int GetTypeOfColumn(int col);
  //...etc...
}

//EDIT:
Grid<int>::GetTypeofColumn(int col) {
   return col == 0 ? STRING_COL_TYPE : INT_COL_TYPE;
}
Grid<string>::GetTypeofColumn(int col) {
   return STRING_COL_TYPE;
}
//End EDIT

class Foo {
  Grid<int>* aBunchOfNumbers;
  Grid<string>* aBunchOfStrings;
  //...etc...
}

//in some function, say `wants` is an enum, and foo is gotten from somewhere:
Foo* foo; 
switch wants {
  case NUMBERS:
    std::cout << "Rows: " << foo->aBunchOfNumbers->GetRows() << std::endl;
    std::cout << "Col0 is: " << foo->aBunchOfNumbers->GetTypeofColumn(0) << std::endl;
    //...etc...
    break;
  case STRINGS:
    std::cout << "Rows: " << foo->aBunchOfNumbers->GetRows() << std::endl;
    std::cout << "Col0 is: " << foo->aBunchOfNumbers->GetTypeofColumn(0) << std::endl;
    //...etc...
    break;
}

这样做会更容易:

Foo* foo;
Grid* grid;
switch wants {
  case NUMBERS:
    grid = foo->aBunchOfNumbers;
    break;
  case STRINGS:
    grid = foo->aBunchOfStrings;
    break;
}
std::cout << "Rows: " << grid->GetRows() << std::endl;
std::cout << "Col0 is: " << grid->GetTypeofColumn(0) << std::endl;
//...etc...

如果我使用这样的子类:http://ideone.com/MPKy1w

,同样如此

我知道类模板几乎基本上都是宏以及编译器实际如何编译它们,但是没有办法一般性地引用特化并节省重复吗?

(我在这里故意使用指针,我在实际代码中别无选择,我无法在这里复制)

1 个答案:

答案 0 :(得分:6)

使用所需方法创建类(“interface”)。可以这样做是因为您的方法不依赖于模板参数T

class GridOperations {
    virtual int GetRows() = 0;
    virtual int getTypeOfColumn(int col) = 0;
    virtual ~GridOperations() {}
};

现在从上面的类继承Grid:

template<T>
class Grid : public GridOperations {
  int GetRows() { /* impl */ }
  int GetTypeOfColumn(int col) { /* impl */ }
};

现在您可以将Grid<int>*Grid<string>*同时投放到GridOperations*

Foo* foo;
GridOperations* ops;
switch wants {
  case NUMBERS:
    ops = foo->aBunchOfNumbers;
    break;
  case STRINGS:
    ops = foo->aBunchOfStrings;
    break;
}
std::cout << "Rows: " << ops->GetRows() << std::endl;
std::cout << "Col0 is: " << ops->GetTypeofColumn(0) << std::endl;

奖励:您甚至可以使用std::map<WantEnumType, GridOperations*>来避免令人讨厌的切换阻止。