我发现自己经常从vector
删除元素,而不关心维护顺序,这意味着使用erase-remove会浪费。最好将要移除的元素与最后一个元素交换pop_back()
。标准库中似乎没有任何东西可以做到这一点,所以我正在尝试编写自己的模板,但我真的没有掌握模板语法。
我写了这个:
template<typename T>
void unordered_erase(std::vector<T>& vec, const std::vector<T>::iterator& it)
{
if (it != vec.end())
{
std::swap(vec.back(), *it);
vec.pop_back();
}
}
然而编译器抱怨。
error: need ‘typename’ before ‘std::vector<_RealType>::iterator’ because ‘std::vector<_RealType>’ is a dependent scope
所以我改变它并编译。
template<typename T>
void unordered_erase(std::vector<T>& vec, const typename std::vector<T>::iterator& it)
{
if (it != vec.end())
{
std::swap(vec.back(), *it);
vec.pop_back();
}
}
我真正不明白的是编译器如何推断std::vector<T>
而不是std::vector<T>::iterator
?
答案 0 :(得分:4)
编译器能够推导出类型T
。 std::vector<_RealType>::iterator
未被推断,它是std::vector
的嵌入式类型。
需要typename
,以便编译器可以从成员变量名中消除嵌入类型名称的歧义。
来自cppreference;
在模板的声明或定义(包括别名模板)中,除了关键字{{{}之外,不是当前实例化成员且依赖于模板参数的名称不被视为类型使用1}} 或者除非它已经被建立为类型名称,例如使用
typename
声明或用于命名基类。
当存在歧义时,名称依赖于模板参数,编译器必须假定名称是成员变量,而不是类型。