1

首先道歉,我不确定我的问题标题是否准确地解释了我的问题 - 我已经通过谷歌查看过,但我不确定我的搜索查询中需要哪些术语,所以答案可能已经在那里(甚至在 StackOverflow 上)。

我有一个模板类,它基本上如下所示 - 它使用单例模式,因此一切都是静态的,我不是在寻找关于为什么我将键存储在一个集合中并使用字符串等的评论,除非它实际上提供了一个解决方案。这门课还有更多内容,但这与问题无关。

template<typename T>
class MyClass 
{
private:
  //Constructor and other bits and peices you don't need to know about
  static std::set<std::string> StoredKeys;
public:
  static bool GetValue(T &Value, std::string &Key)
  {
    //implementation
  }

  static SetValue(const T Value, std::string &Key)
  {
    //implementation
    StoredKeys.Insert(Key);
  }

  static KeyList GetKeys()
  {
    return KeyList(StoredKeys);
  }
};

稍后在应用程序的其他部分中,我想获取所有值的所有键 - 无论类型如何。

虽然我相当有信心,目前该类只使用了 3 或 4 种类型,所以我可以编写如下内容:

KeyList Keys = MyClass<bool>::GetKeys();
Keys += MyClass<double>::GetKeys();
Keys += MyClass<char>::GetKeys();

每次使用新类型时都需要更新。如果它没有在任何地方使用,它也有实例化类的缺点。

我认为(再次我可能是错的)元编程是这里的答案,也许是某种宏?

我们正在使用 boost,所以我猜 MPL 库在这里可能有用吗?

STL 的这个方面对我来说有点新,所以我很乐意阅读并尽可能多地学习,只要我确切知道我需要学习什么来设计解决方案。

4

3 回答 3

0

移入StoredKeys非模板基类class MyClassBase,或将AllStoredKeys静态成员添加到非模板基类。

或者,创建一个调用 from 的静态 init 方法,SetValue该方法添加指向StoredKeys静态列表的指针。

于 2012-06-13T10:37:59.870 回答
0

没有魔法。如果您需要枚举用于MyClass在程序中实例化的所有类型,那么您必须在某处显式枚举它们。不知何故。而且您必须在列表更改时手动更新列表。

使用模板元编程,您需要手动更新的位置数量可以减少到一个,但您确实需要那个位置。

幸运的是,在这个特定的问题中,您不需要枚举所有类型。您只需将所有密钥存储在一组中,而不是将它们分成几组。您可以创建一个通用的非模板库MyClass并添加到static std::set<std::string> StoredKeys那里(或者multiset如果在不同类型特定的集合中可能存在相同的键,则可以将其添加到该库中)。

于 2012-06-13T10:46:38.453 回答
0

第一个回答:不可能!模板类实际上没有共同的“泛型”(如在 java 中),而是一个单独的类,它们彼此之间没有任何关系。

第二个回答:有一个解决方法。可以定义一个基类,该基类MyClassBase定义所有模板化子类共享的属性。问题是您在这里有一个单例模式,这可能会使情况更加复杂。我认为解决方案可能如下所示:

class MyClassBase {
  static std::vector<MyClassBase*> childs;

  static KeyList getAllKeys(){
       //iterate over childs here and call ->GetKeys
  }

  virtual KeyList GetKeys() = 0;

  template<typename T>
  static T* instance() {
     T* instance = MyClass<T>::instance();
     if(std::find(childs.begin(), childs.end(), instance) != childs.end()){
       childs.push_back(instance);
     }
     return instance;
  }
};

请原谅我的任何语法错误;我只是在 Stackoverflow 编辑器中输入了它,但我认为它应该让我的观点清楚。

编辑: 我刚刚看到我也命名了子类的单例方法instance()。这可能行不通。给它一些其他的名字privateInstance()。然后你必须T* instance = MyClass<T>::instance();改为T* instance = MyClass<T>::privateInstance();

于 2012-06-13T10:50:03.363 回答