我写了一个模板函数来翻转我的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给了我一个语法错误:
意外的令牌“标识符”,预期的“;”
我不知道我在做什么错。
答案 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;
}
事实上,我确实做到了;两个星期前。 :)
(您也可以考虑一些.emplace
和std::move
等,具体取决于A
和B
可能是什么,尽管您不能从映射键,这只会是“有用的”。)
答案 1 :(得分:2)
原因是std::map<A,B>::iterator
是一个从属名称(粗略地说,它是在模板函数中,并且取决于模板的参数A
和B
)。因此,必须在其前面加上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及更高版本),让编译器使用auto
和std::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;
}