c++ - 基于策略的模板设计 : How to access certain policies of the class?

标签 c++ oop templates template-meta-programming policy

我有一个使用多个模板化策略的类。它在以下示例中称为 Dish。我将许多这样的 Dish 存储在 vector 中(使用指向简单基类的指针),但随后我想提取并使用它们。但我不知道他们的确切类型。

这是代码;它有点长,但非常简单:

#include <iostream>
#include <vector>

struct DishBase {
  int id;
  DishBase(int i) : id(i) {}
};

std::ostream& operator<<(std::ostream& out, const DishBase& d) {
  out << d.id;
  return out;
}

// Policy-based class:
template<class Appetizer, class Main, class Dessert>
class Dish : public DishBase {
  Appetizer appetizer_;
  Main main_;
  Dessert dessert_;
public:
  Dish(int id) : DishBase(id) {}
  const Appetizer& get_appetizer() { return appetizer_; }
  const Main& get_main() { return main_; }
  const Dessert& get_dessert() { return dessert_; }
};

struct Storage {
  typedef DishBase* value_type;
  typedef std::vector<value_type> Container;
  typedef Container::const_iterator const_iterator;
  Container container;
  Storage() {
    container.push_back(new Dish<int,double,float>(0));
    container.push_back(new Dish<double,int,double>(1));
    container.push_back(new Dish<int,int,int>(2));
  }
  ~Storage() {
    // delete objects
  }
  const_iterator begin() { return container.begin(); }
  const_iterator end() { return container.end(); }  
};

int main() {
  Storage s;
  for(Storage::const_iterator it = s.begin(); it != s.end(); ++it){
    std::cout << **it << std::endl;
    std::cout << "Dessert: " << *it->get_dessert() << std::endl; // ??
  }
  return 0;
}

棘手的部分在这里,在 main() 函数中:

    std::cout << "Dessert: " << *it->get_dessert() << std::endl; // ??

我怎样才能获得甜点?我什至不知道 Dessert 类型(它是模板化的),更不用说我从存储中获取的对象的完整类型了。

这只是一个玩具示例,但我认为我的代码可以简化为这样。我只想传递那些 Dish 类,代码的不同部分将访问它的不同部分(在示例中:它的开胃菜、主菜或甜点)。

最佳答案

在我看来,您所拥有的并不是完全基于策略的设计...如果是,您的类(class)应该已经实际实现(即扩展)这些策略。

现在,回到您的问题/示例。在您的容器中,您存储了一个“DishBase*”。正确的?从那时起,您将丢失关于集合中对象的实际类型的任何编译时信息。所以,恐怕你试图做的事情被证明是不可能的。

可以做的是使用实际的基于策略的设计,例如。

template<class Appetizer, class Main, class Dessert>
class Dish : public DishBase, Appetizer, Main, Dessert {
}

然后,您可以简单地使用 dynamic_cast 在运行时检查您是否可以将您的对象转换为任何具体的 Appetizer/Dessert/Main。

但是根据您的描述,我得到的印象是您实际上需要抽象基类(即抽象基类可能是对您有意义的设计,而不是策略)。

关于c++ - 基于策略的模板设计 : How to access certain policies of the class?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2394519/

相关文章:

c++ - 在不知道字符串宽度的情况下左右对齐

c++ - {1, 2} 是一个值吗?如果是,它的类型是什么?如果不是,为什么可以将其分配给初始化列表?

c++ - 编辑控件中的搜索图标与输入区域重叠

c++ - Pthread实例变量运行类中的方法

java - 实现java对象之间通信的正确方法是什么?

JavaFX 按钮对第二次单击而不是第一次单击使用react

模板声明中省略了 C++ 类型参数。但是,在成员函数的定义中又如何呢?

C++使用=从定义的父类(super class)转换为子类

c++ - 将多个基础结构组合成自定义类型

c++ - 无法继承 clang 和 gcc 中同一类的显式模板特化