为什么我的地图迭代器中出现语法错误?

时间:2019-03-24 23:14:03

标签: c++

我写了一个模板函数来翻转我的std::map键和值。

#include <map>
#include <iterator>

template <typename A, typename B>
std::map<B, A> flip_map(std::map<A, B> &src)
{
    std::map<B, A> dst;
    for (std::map<A, B>::iterator it = src.begin(); it != src.end(); ++it)
    {
        dst.insert(std::pair<B, A>(it->second, it->first));
    }
    return dst;
}

VS给了我一个语法错误:

  

意外的令牌“标识符”,预期的“;”

我不知道我在做什么错。

2 个答案:

答案 0 :(得分:5)

GCC tells you more clearly what's wrong:出于神秘的C ++原因,您需要在那里typename

赞:

for (typename std::map<A, B>::iterator it = src.begin(); it != src.end(); ++it)
//   ^^^^^^^^

进一步阅读:


我会这样写:

#include <map>

template <typename A, typename B>
std::map<B, A> flip_map(const std::map<A, B>& src)
{
    std::map<B, A> dst;

    for (const auto& p : src)
        dst.insert(std::make_pair(p.second, p.first));

    return dst;
}

事实上,我确实做到了;两个星期前。 :)

(您也可以考虑一些.emplacestd::move等,具体取决于AB可能是什么,尽管您不能从映射键,这只会是“有用的”。)

答案 1 :(得分:2)

原因是std::map<A,B>::iterator是一个从属名称(粗略地说,它是在模板函数中,并且取决于模板的参数AB)。因此,必须在其前面加上typename关键字。

template <typename A, typename B>
std::map<B, A> flip_map(std::map<A, B> &src)
{
    std::map<B, A> dst;
    for (typename std::map<A, B>::iterator it = src.begin(); it != src.end(); ++it)
    {
        dst.insert(std::pair<B, A>(it->second, it->first));
    }
    return dst;
}

另外,您最好将src指定为const,并使用const_iterator而不是iterator,即

template <typename A, typename B>
std::map<B, A> flip_map(const std::map<A, B> &src)
{
    std::map<B, A> dst;
    for (typename std::map<A, B>::const_iterator it = src.begin(); it != src.end(); ++it)
    {
        dst.insert(std::pair<B, A>(it->second, it->first));
    }
    return dst;
}

或(C ++ 11及更高版本),让编译器使用autostd::make_pair为您做类型推断。这样可以避免程序员担心依赖名称。

template <typename A, typename B>
std::map<B, A> flip_map(const std::map<A, B> &src)
{
    std::map<B, A> dst;
    for (const auto &e : src)
    {
        dst.insert(std::make_pair(e.second, e.first));
    }
    return dst;
}