我试图做一个间隔树的粗略抽象实现,但我得到一个奇怪的错误.我返回a的所有函数std::map<ui16, Node>::iterator都给出了错误:
错误C2146:语法错误:缺少';' 在标识符"FOO"之前
FOO函数的名称在哪里.
ui16简直就是一个typedef unsigned short.
有任何想法吗?
#include "stdafx.h"
#include <map>
//Very rough implementation of a specialized interval tree
//TODO: Replace std::map with a custom red-black tree implementation or something similar
template <typename T>
class IntervalTree {
public:
struct Node {
Node(T Data, ui16 Length) : data(Data), length(Length) {}
T data;
ui16 length;
};
inline void clear() {
std::map<ui16, Node>().swap(_tree);
}
inline std::map<ui16, Node>::iterator getInterval(ui16 index) const {
auto it = _tree.lower_bound(index);
if (it->first != index) {
return it--;
}
return it;
}
inline std::map<ui16, Node>::iterator insert(std::pair<ui16, Node> pair) {
return _tree.insert(pair);
}
std::map<ui16, Node>::iterator insert(ui16 index, T data) {
//Find containing interval
auto it = _tree.lower_bound(index);
if (it->first != index) {
it--;
}
//Its already in the tree
if (it->second.data == data) {
return it;
}
//If the interval is only 1, just change its value
if (it->second.length == 1) {
it->second.data = data;
return it;
}
//Check if its at the right edge of the interval
if (index == it->first + it->second.length - 1) {
auto next = it + 1;
//if it should add to the next interval
if (data == next->second.data) {
it->second.length--;
it = _tree.insert(make_pair(index, Node(data, next->second.length + 1)));
_tree.erase(next);
return it;
} else { //else we should add an interval and modify left interval
//Modify left interval
it->second.length--;
//Insert new interval
return _tree.insert(make_pair(index, Node(data, 1)));
}
} else if (index == it->first) { //if its at the beginning of the interval
//Insert right interval
_tree.insert(make_pair(index + 1, Node(it->second.data, it->second.length - 1)));
_tree.erase(it);
_tree.insert(make_pair(index, Node(data, 1)));
} else { //else its in the middle of the interval
//Insert right interval
_tree.insert(make_pair(index + 1, Node(it->second.data, it->second.length - (index - it->first) - 1)));
//Modify left interval
it->second.length = index - it->first;
//Insert new middle interval
return _tree.insert(make_pair(index, Node(data, 1)));
}
return _tree.end();
}
inline std::map<ui16, Node>::iterator begin() const { return _tree.begin(); }
inline std::map<ui16, Node>::iterator end() const { return _tree.end(); }
private:
std::map <ui16, Node> _tree;
};
Run Code Online (Sandbox Code Playgroud)
小智 5
C2146给出了一个相当无用的错误消息,但最终问题是你缺少typename有依赖范围的关键字.iterator取决于实例化,std::map<ui16, Node>并要求typename关键字消除您的使用歧义.有关详细信息,请参阅我在哪里以及为什么要放置"模板"和"typename"关键字?.有关更有用的错误消息,请参阅gcc中的以下示例:
main.cpp:83:12: error: need ‘typename’ before
‘std::map<short unsigned int, IntervalTree<T>::Node>::iterator’
because ‘std::map<short unsigned int, IntervalTree<T>::Node>’ is a dependent scope
inline std::map<ui16, Node>::iterator begin() const { return _tree.begin(); }
Run Code Online (Sandbox Code Playgroud)
只需更换std::map<ui16, Node>::iterator,typename std::map<ui16, Node>::iterator你就会好起来.