【问题标题】:I am confused about constant, constant references, references to constants, ... (including example code)我对常量、常量引用、对常量的引用感到困惑……(包括示例代码)
【发布时间】:2017-11-29 01:16:30
【问题描述】:

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

#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&lt;_Ty, _Container&gt;::push [with _Ty=Vertex *, _Container=std::deque&lt;Vertex *, std::allocator&lt;Vertex *&gt;&gt;]" matches the argument list
  • error2: E0304 no instance of overloaded function "std::set&lt;_Kty, _Pr, _Alloc&gt;::insert [with _Kty=Vertex *, _Pr=std::less&lt;Vertex *&gt;, _Alloc=std::allocator&lt;Vertex *&gt;]" matches the argument list
  • error3: E0304 no instance of overloaded function "std::set&lt;_Kty, _Pr, _Alloc&gt;::find [with _Kty=Vertex *, _Pr=std::less&lt;Vertex *&gt;, _Alloc=std::allocator&lt;Vertex *&gt;]" matches the argument list
  • error4: E0304 no instance of overloaded function "std::stack&lt;_Ty, _Container&gt;::push [with _Ty=Vertex *, _Container=std::deque&lt;Vertex *, std::allocator&lt;Vertex *&gt;&gt;]" matches the argument list
  • error5: E0304 no instance of overloaded function "std::set&lt;_Kty, _Pr, _Alloc&gt;::insert [with _Kty=Vertex *, _Pr=std::less&lt;Vertex *&gt;, _Alloc=std::allocator&lt;Vertex *&gt;]" matches the argument list

我意识到我并不像我想象的那样理解引用。我使用了谷歌,我得到的点击重申了我对引用的理解,但不要触及我不理解的部分(导致这些错误)。

我还取消了迭代器的引用,然后用&amp;得到了迭代器所指向的实际对象的地址,不知道是我误解了迭代器的工作方式,还是只是一个问题参考文献。

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

【问题讨论】:

  • 阅读一本好的 C++ 教科书。
  • 从这里开始:C++ Const Usage Explanation 常量在不应更改参数时防止分配参数。实际上,我可以防止错误进入代码。

标签: c++ reference iterator constants


【解决方案1】:

在您的情况下,void DFS(const Vertex&amp; v) v 是对常量 var 的引用。也就是说,你保证函数不会修改对象。

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

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

在这里,您试图违反协议。您正在尝试在容器中分配一个指向常量对象v 的指针,该容器用于指向可修改对象的指针。如果允许这样做,您将能够通过指针修改v 引用的值。因此,这是不允许的,编译器会在此处产生错误。

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

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

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

现在,visited.find(&amp;(*iter)) 与 set::iterator 的实现有关。显然,运算符“*”返回的值引用了一个常量值,导致再次尝试从“常量”转换为非常量。

因此,使用 const Vertex * 参数声明 stack 和 visited 应该可以解决您的编译问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-01
    • 1970-01-01
    • 2019-02-05
    • 1970-01-01
    • 1970-01-01
    • 2018-06-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多