我编写了一个用于翻转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给了我一个语法错误:
标识符意外的标记‘
’,应为';‘
我不知道我做错了什么。
发布于 2019-03-25 07:17:54
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
可能是什么,尽管由于您不能从映射键移动,这只会是“某种有用的”。)
发布于 2019-03-25 08:02:23
原因是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;
}
https://stackoverflow.com/questions/55329483
复制相似问题