代码在 g++ 上本地编译4.4.1,但不在 codepad.org 上(g++ 4.1.2)? (参考参考问题)?)

发布于 2024-08-16 10:08:22 字数 1411 浏览 11 评论 0原文

我正在编写一个测试用例来解决我的应用程序中的一个更大的问题。我结束了在键盘上尝试一些代码,发现在我的本地计算机(g++ 4.4.1,带 -Wall)上编译的一些代码没有在键盘(g++ 4.1.2)上编译,即使我的本地计算机有更新的版本g++ 版本。

Codepad 将此称为引用错误的引用,我对此进行了查找并找到了一些信息。看起来拥有一个 stl 引用容器并不是一个好主意。这是否意味着我需要定义自己的 PairPages 类?如果是这样的话,为什么它首先要在本地编译呢?这是怎么回事?

键盘链接:http://codepad.org/UAaJI1rl

#include <deque>
#include <utility>
#include <iostream>

using namespace std;

class Page {
  public:
    Page() : number_(++count) {}
    int getNum() const { return number_; }
  private:
    static int count;
    int number_;
};

int Page::count = 0;

class Book {
  public:
    Book() : currPageIdx_(3) {
      int numPages = 5;
      while (numPages > 0) {
        pages_.push_back(Page());
        numPages--; // oops
      }
    }
    pair<const Page&, const Page&> currPages() { return pagesAt(currPageIdx_); }
    pair<const Page&, const Page&> pagesAt(int pageNo) { return make_pair(pages_[pageNo - 1], pages_[pageNo]); }
    //const Page& currPages() { return pagesAt(currPageIdx_); }
    //const Page& pagesAt(int pageNo);
  private:
    deque<Page> pages_;
    int currPageIdx_;
};

int main() {
    Book book;
    cout << book.pagesAt(3).first.getNum() << endl;
    cout << book.currPages().first.getNum() << endl;
}

I was writing a test case out to tackle a bigger problem in my application. I ended trying some code out on codepad and discovered that some code that compiled on my local machine (g++ 4.4.1, with -Wall) didn't compile on codepad (g++ 4.1.2), even though my local machine has a newer version of g++.

Codepad calls this a reference to reference error, which I looked up and found a litle information on. It looks like it's not a good idea to have a stl container of references. Does this mean I need to define my own PairPages class? And if this is the case, why did it compile locally in the first place? What's going on?

codepad link: http://codepad.org/UAaJI1rl

#include <deque>
#include <utility>
#include <iostream>

using namespace std;

class Page {
  public:
    Page() : number_(++count) {}
    int getNum() const { return number_; }
  private:
    static int count;
    int number_;
};

int Page::count = 0;

class Book {
  public:
    Book() : currPageIdx_(3) {
      int numPages = 5;
      while (numPages > 0) {
        pages_.push_back(Page());
        numPages--; // oops
      }
    }
    pair<const Page&, const Page&> currPages() { return pagesAt(currPageIdx_); }
    pair<const Page&, const Page&> pagesAt(int pageNo) { return make_pair(pages_[pageNo - 1], pages_[pageNo]); }
    //const Page& currPages() { return pagesAt(currPageIdx_); }
    //const Page& pagesAt(int pageNo);
  private:
    deque<Page> pages_;
    int currPageIdx_;
};

int main() {
    Book book;
    cout << book.pagesAt(3).first.getNum() << endl;
    cout << book.currPages().first.getNum() << endl;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

奶茶白久 2024-08-23 10:08:22

引用的向量(或任何 STL 容器)确实是一个坏主意,当您简单地查看任何 STL 容器(ISO C+ +03 23.1[lib.container.requirements])。它首先说“容器是存储其他对象的对象”。我们可以在这里停下来,因为引用不是 C++ 中的对象(与指针不同;请注意,C++ 术语中的“对象”并不意味着“类的实例”!)。但是,此外,它要求 TAssignable,其要求参考类型 T& - if T > 本身就是某种引用类型 U&,那么构造的类型将是 U& &,它(引用到引用)在 C++ 中是非法的。

如果您确实想要一个不管理对象生命周期的容器,那么您应该使用指针容器。如果您更喜欢引用的安全性(例如缺少指针算术和空值),则可以使用 std::tr1::reference_wrapper 类,它是引用的可复制构造和可分配包装器。

A vector (or any STL container) of references is indeed a bad idea, as obvious when you simply look at requirements for element type T of any STL container (ISO C++03 23.1[lib.container.requirements]). It starts off by saying that "containers are objects that store other objects". We can stop right here, because a reference is not an object in C++ (unlike, say, a pointer; note that "object" in C++ parlance doesn't mean "instance of class"!). But, furthermore, it requires T to be Assignable, the requirements for which refer to type T& - if T is itself some reference type U&, then the constructed type would be U& &, which (reference to reference) is illegal in C++.

If you really want to have a container that doesn't manage lifetimes of objects, then you should use a container of pointers. If you prefer the safety of references (e.g. lack of pointer arithmetic and null value), you can use std::tr1::reference_wrapper<T> class, which is copy constructible and assignable wrapper for a reference.

无人问我粥可暖 2024-08-23 10:08:22

关于海报的无限循环问题:您的代码无限循环,因为在 Book 构造函数中,计数器 numPages 永远不会减少,因此 while 语句永远不会停止,直到内存耗尽。

仅使用 for 循环通常更容易发现此类错误:

Book() : currPageIdx_(3) {
  for(int numPages = 0; numPages < 5; ++numPages) {
    pages_.push_back(Page());
  }
}

On the poster's infinite loop problem: Your code loops indefinitely because in the Book constructor the counter numPages is never decreased, thus the while statement never halts until you run out of memory.

It's usually easier to spot these kind of errors by just using a for-loop:

Book() : currPageIdx_(3) {
  for(int numPages = 0; numPages < 5; ++numPages) {
    pages_.push_back(Page());
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文