【问题标题】:Template class that takes a template class as template won't compile将模板类作为模板的模板类不会编译
【发布时间】:2012-05-04 09:45:17
【问题描述】:

我正在尝试创建一个将地图作为模板参数的类。特别是它应该能够采用 std::map 和 boost::ptr_map。目前我正在尝试这个:

template <template<typename, typename> class MAP, typename KEYTYPE, typename DATATYPE>
class RestrictedMapBase
{
   /* bunch of methods ... */
}

这个类被另外两个类继承,一个用于std::map,一个用于boost::ptr_map。

template <typename KEYTYPE, typename DATATYPE>
class RestrictedMap: public RestrictedMapBase<std::map, KEYTYPE, DATATYPE>
{
   /* Bunch of methods ... */
};

template <typename KEYTYPE, typename DATATYPE>
class RestrictedPointerMap: public RestrictedMapBase<boost::ptr_map, KEYTYPE, DATATYPE>
{
   /* Bunch of methods ... */
};

但在编译时出现以下错误:

RestrictedMap.h(166):错误 C3201:模板参数列表 类模板 'std::map' 与模板参数列表不匹配 对于模板参数 'MAP' RestrictedMap.h(183):见参考 类模板实例化 'STLUtils::RestrictedMap' 正在编译

RestrictedMap.h(186):错误 C3201:模板参数列表 类模板 'boost::ptr_map' 与模板参数不匹配 模板参数 'MAP' RestrictedMap.h(203) 的列表:参见 引用类模板实例化 'STLUtils::RestrictedPointerMap' 正在编译

谁能指出我做错了什么的正确方向?谢谢。

【问题讨论】:

    标签: c++ templates


    【解决方案1】:

    std::map 需要一个模板参数来定义它的映射。见下文:

    template <typename KEYTYPE, typename DATATYPE>
    class RestrictedMap: public RestrictedMapBase<std::map<KEYTYPE, DATATYPE>, KEYTYPE, DATATYPE>
    {
       /* Bunch of methods ... */
    };
    

    您的基类模板参数KEYTYPE 和DATATYPE 然后就变得多余了。您可以用 std::map 类中提供的 typedef 替换它们:

    std::map<_Kty, _Ty>::key_type; // This is the same as KEYTYPE
    std::map<_Kty, _Ty>::mapped_type; // This is the same as DATATYPE
    

    我会像这样重写你的课程(我还没有测试过):

    template <typename Map>
    class RestrictedMap
    {
    public: // Typedefs
        typedef typename Map::key_type KeyType;
        typedef typename Map::mapped_type MapType;
    
    public: // Methods
        // TODO: Write your methods here.
        void Add(const KeyType &key, const MapType &map);
    
    private: // Members
        Map m_map;
    };
    

    然后你可以像这样选择你的地图(再次未经测试):

    typedef RestrictedMap<std::map<int, int>> StlMap; // TODO: Change your map's key and data type
    typedef RestrictedMap<boost::ptr_map<int, int>> BoostMap; // TODO: Change your map's key and data type
    

    此处提供完整示例 - http://ideone.com/U3AkV

    【讨论】:

    • 你为什么给我看一个OP原始代码的代码示例?我的代码编译:ideone.com/U3AkV
    【解决方案2】:

    类模板 std::map 有 4 个参数:

    template <typename _Key, typename _Tp, typename _Compare = std::less<_Key>,
              typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
    class map
    

    因此它不能通过template&lt;typename, typename&gt; 传递,就像您不能将指向 3 参数函数的指针分配给指向 2 参数函数的指针一样。

    解决方案是将要使用的确切类型传递给RestrictedMapBase:

    template <typename MAP>
    class RestrictedMapBase
    {
       typedef typename MAP::key_type KEYTYPE;
       typedef typename MAP::mapped_type DATATYPE;
    };
    

    您的初始设计还限制了您的类的用户,因为他们无法为键指定比较函数(如果他们想使用哈希表,则为哈希函数)和分配器。

    【讨论】:

    • 我接受了这个作为答案,因为它处理了我犯的错误。即使我使用 Mark Ingram 的答案来解决我的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-28
    • 1970-01-01
    相关资源
    最近更新 更多