【问题标题】:Comparison implementation C++ map incomplete type not allowed比较实现 C++ 映射不完整类型不允许
【发布时间】:2013-07-30 09:37:33
【问题描述】:

我正在尝试实现一个自定义 C++ 比较函数,以传递给 std::map。 按照map API 中的说明,我实现了:

 35 typedef std::pair<uint64_t, KeyHash> TabletKey;
 36 
 37 class CmpTabletKey {
 38     public:
 39         bool operator()(const TabletKey& key1, const TabletKey& key2) const {
 40             if (!(key1.first < key2.first)) {
 41                 return false;
 42             }
 43             if (!(key2.first < key1.first)) {
 44                 return false;
 45             }
 46 
 47             return true;
 48         }
 49 };

map 是属性的类中,我有:

 55 class ObjectFinder {
 56   public:
 57     class TableConfigFetcher; // forward declaration, see full declaration below
 58     class CmpTabletKey;
        // .. more code here
      private:
 97     std::map<TabletKey, ProtoBuf::Tablets::Tablet, CmpTabletKey> tableMap;
     }

我收到以下错误:

/home/ribeiro.phillipe/ramcloud/src/ObjectFinder.h:97:   instantiated from here
/usr/lib/gcc/x86_64-redhatlinux/4.4.6/../../../../include/c++/4.4.6/bits/stl_tree.h:453: 
error: incomplete type ‘RAMCloud::ObjectFinder::CmpTabletKey’ not allowed
In file included from /usr/lib/gcc/x86_64-redhat-linux/4.4.6/../../../../include/c++/4.4.6/map:60,

我不知道为什么会这样。另外,我愿意使用std::less 实现less

【问题讨论】:

  • 您不能使用前向声明来实例化std::map。一般来说,标准库容器需要完整的类型来实例化。
  • @juanchopanza 你能举个例子吗?
  • 在实例化地图之前确保CmpTabletKey 的定义可用。

标签: c++ dictionary ramcloud


【解决方案1】:

你在类中声明了第二个CmpTabletKey ObjectFinder;实例化地图时,您在 类,所以这是编译器找到的。只需放下 class CmpTabletKey; 类内的语句(或更改它 到 typedef 到 ::CmpTabletKey,或移动整个定义 CmpTabletKey 在类 ObjectFinder 内。

另外,你的比较功能看起来有点奇怪。它看起来 对我来说,如果键相等,它只能返回true, 它没有定义排序关系。如果你只想 比较第一个字段:

bool operator()( TabletKey const& lhs, TabletKey const& rhs ) const
{
    return lhs.first < rhs.first;
}

应该可以解决问题。

【讨论】:

    【解决方案2】:

    典型地,作为模板参数传递给标准库模板的类型必须在模板实例化时完全定义。 (智能指针模板除外)
    这也适用于std::map 的比较器,所以前向声明是不够的,你必须提供CmpTabletKey 的完整定义来定义你的

    std::map<TabletKey, ProtoBuf::Tablets::Tablet, CmpTabletKey> tableMap;
                                                 //^^^------- needs full definition
    

    【讨论】:

    • 完全同意,但我应该将CmpTabletKey 放在ObjectFinder 类的什么位置?我在ObjectFinder 类声明之上实现了它
    • @philippe 但是你声明了一个嵌套在 ObjectFinder 类中的新的,这是不完整的。
    • @philippe 如果你在类外定义它,你不需要在类内声明。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-08
    • 1970-01-01
    • 2019-10-08
    • 2011-05-13
    • 2011-08-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多