我对常量,常量引用,常量引用,...(包括示例代码)感到困惑

时间:2017-11-29 01:16:31

标签: c++ reference iterator const

我正在尝试编写一个令我满意的图形数据结构实现。 (将邻接列表维护为集合而不是链接列表。)无论如何,我试图使用引用和迭代器并写下这个:

#include <iostream>
#include <string>
#include <set>
#include <stack>

class Vertex {
    std::string name;
    std::set<Vertex> edges;
public:
    Vertex(std::string name) : name(name) {}

    std::string vertexName() const {
        return name;
    }

    std::set<Vertex> outEdges() const {
        return edges;
    }

    void addEdge(const Vertex& other) {
        edges.insert(other);
    }

    void removeEdge(const Vertex& other) {
        edges.erase(other);
    }

    int outDegree() {
        return edges.size();
    }
};

bool operator<(const Vertex& v1, const Vertex& v2) {
    return (v1.vertexName().compare(v2.vertexName()) < 0);
}

void DFS(const Vertex& v) {
    std::stack<Vertex*> stack;
    std::set<Vertex*> visited;


    stack.push(&v);             // error1
    visited.insert(&v);         // error2

    while (!stack.empty()) {
        Vertex* vert_ptr = stack.top();
        stack.pop();

        std::cout << vert_ptr->vertexName() << std::endl;

        //
        for (std::set<Vertex>::iterator iter = vert_ptr->outEdges().begin(); iter != vert_ptr->outEdges().end(); iter++) {
            if (visited.find(&(*iter)) != visited.end()) {      // error3
                stack.push(&(*iter));                           // error4
                visited.insert(&(*iter));                       // error5
            }
        }
    }
}

int main() {
    Vertex a = Vertex("a");
    Vertex b = Vertex("b");
    Vertex c = Vertex("c");

    DFS(a);

    getchar();
    return 0;
}

我收到以下错误:

  • error1: E0304 no instance of overloaded function "std::stack<_Ty, _Container>::push [with _Ty=Vertex *, _Container=std::deque<Vertex *, std::allocator<Vertex *>>]" matches the argument list
  • error2: E0304 no instance of overloaded function "std::set<_Kty, _Pr, _Alloc>::insert [with _Kty=Vertex *, _Pr=std::less<Vertex *>, _Alloc=std::allocator<Vertex *>]" matches the argument list
  • error3: E0304 no instance of overloaded function "std::set<_Kty, _Pr, _Alloc>::find [with _Kty=Vertex *, _Pr=std::less<Vertex *>, _Alloc=std::allocator<Vertex *>]" matches the argument list
  • error4: E0304 no instance of overloaded function "std::stack<_Ty, _Container>::push [with _Ty=Vertex *, _Container=std::deque<Vertex *, std::allocator<Vertex *>>]" matches the argument list
  • error5: E0304 no instance of overloaded function "std::set<_Kty, _Pr, _Alloc>::insert [with _Kty=Vertex *, _Pr=std::less<Vertex *>, _Alloc=std::allocator<Vertex *>]" matches the argument list

我意识到我不理解参考文献以及我以为我做过。我使用谷歌,我得到的点击重申我对引用的理解,但不要触及我不理解的部分(这导致了这些错误)。

我也取消引用迭代器,然后使用&来获取迭代器指向的实际对象的地址,并且不知道我是否误解了迭代器的工作方式,或者它是否只是一个引用的问题。

如果有人能够指出我对所有这些的一个很好的参考,我将不胜感激。 :(

1 个答案:

答案 0 :(得分:0)

在您的情况下,v std::stack<Vertex*> stack; std::set<Vertex*> visited; 是对var的引用,该var是常量。换句话说,你承诺该函数不会修改对象。

v

以上是指向对象的指针的容器,是常量,因此是可修改的。

在这里,您试图违反协议。您正在尝试在容器中分配指向常量对象v的指针,该容器用于指向可修改对象的指针。如果允许这样做,您将能够通过指针修改stack.push(&v); // error1 visited.insert(&v); // error2 引用的值。所以,这是不允许的,编译器会在这里产生错误。

std::stack<const Vertex*> stack;
std::set<const Vertex*> visited;

所以,你需要使用指向常量的指针来声明容器:

visited.find(&(*iter))

现在,const Vertex *与set :: iterator的实现有关。显然,运算符'*'返回的值引用了一个常量值,导致另一次从'const'到非const的转换尝试。

因此,使用innerText参数声明堆栈访问应解决您的编译问题。