我想开发一个函数,它接受任何类型的向量并返回一个映射(类似于 python 中的计数器)


template<class T>
map<T,int> counter(vector<T> a)
{
    map<T,int> b;
    pair<map<T,int>::iterator ,bool> pos; //This line shows compiler message
    for(int i=0;i<a.size();++i)
    {
        pos=b.insert(make_pair(a[i],1));
        if(!(pos.second))
        {
            b[pos.first -> first]++;
        }
    }
    return b;
}

这是使用模板的代码。

map<int,int> counter(vector<int> a)
{
    map<int,int> b;
    pair<map<int,int>::iterator ,bool> pos;
    for(int i=0;i<a.size();++i)
    {
        pos=b.insert(make_pair(a[i],1));
        if(!(pos.second))
        {
            b[pos.first -> first]++;
        }
    }
    return b;
}

如果我只为整数重写,这就是函数。整数代码工作正常,第一个则不行。你能解释一下为什么会发生这种情况以及我如何修改它以便我适用于每种数据类型吗?

当你说"第一个工作不正常"时,你是在暗示它由于一些关于iterator的时髦错误而无法编译吗?在模板内部,依赖名称必须使用 typename 标记为类型:

pair<map<T, int>::iterator, bool> pos;

名称iteratorstd::map<T, int> 中的嵌套名称。你只需要使用

pair<typename map<T, int>::iterator, bool> pos;

相反。

就个人而言,我倾向于完全回避这个问题,实现这样的功能:

template<class T>
std::map<T, int> counter(std::vector<T> const& a)
{
    std::map<T, int> result;
    std::for_each(a.begin(), a.end(), [&](T const& value){ ++result[value]; });
    return result;
}

此实现利用了以下事实:operator[]()插入具有值初始化值的新元素(即使用 T() (。换句话说,当映射中有 on 对象时,它将返回对零初始化int的引用。

map<T,int>::iterator是一个

依赖名称,即它依赖于模板参数。您需要告诉编译器它始终命名一个类型,以便可以正确解析它:

pair<typename map<T,int>::iterator ,bool> pos;
//   ^^^^^^^^

有关 typename 关键字以及何时需要使用它的更多信息,请参阅此问题。

最新更新