返回迭代器的函数缺少分号错误

use*_*893 0 c++ tree c++11

我试图做一个间隔树的粗略抽象实现,但我得到一个奇怪的错误.我返回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你就会好起来.

  • 更具体地说,`IntervalTree <T> :: Node`是一个从属名称,因为`IntervalTree`的某些特化可能没有它,或者可能将它作为嵌套类型以外的东西.因此,任何由"IntervalTree <T> :: Node"组成的类型(例如您的地图类型)也都是依赖名称. (3认同)