【问题标题】:Code compiles locally on g++ 4.4.1, but not on codepad.org (g++ 4.1.2)? (reference to reference problem)?)代码在 g++ 4.4.1 上本地编译,但不在 codepad.org (g++ 4.1.2) 上? (参考参考问题)?)
【发布时间】:2009-12-29 09:59:38
【问题描述】:

我正在编写一个测试用例来解决我的应用程序中的一个更大的问题。我结束了在键盘上尝试了一些代码,发现在我的本地机器(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;
}

【问题讨论】:

标签: c++ reference g++ compiler-errors containers


【解决方案1】:

引用 vector(或任何 STL 容器)确实是个坏主意,当您简单地查看任何 STL 容器(ISO C++03 23.1[lib.container)的元素类型 T 的要求时,这一点很明显。要求])。它首先说“容器是存储其他对象的对象”。我们可以在这里停下来,因为引用不是 C++ 中的对象(与指针不同;请注意,C++ 用语中的“对象”并不意味着“类的实例”!)。但是,此外,它要求TAssignable,其要求引用类型T&amp; - 如果T 本身是某个引用类型U&amp;,则构造类型将为U&amp; &amp;,即(reference to reference) 在 C++ 中是非法的。

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

【讨论】:

  • 我只需要一种从应用程序通过 Book::pagesAt(pageNo) 访问两个页面的方法。我可以返回一对指向不在堆中的页面的指针吗?比如:return make_pair(&pages_[pageLeftIdx], &pages_[pageRightIdx]),带有 const 的返回类型 pair?
  • 是的,当然。不必使用 new 创建对象即可传递指针。
【解决方案2】:

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

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

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

【讨论】:

    猜你喜欢
    • 2015-06-10
    • 2015-11-23
    • 2022-06-24
    • 1970-01-01
    • 2016-02-25
    • 1970-01-01
    • 2020-12-31
    • 2015-07-04
    • 1970-01-01
    相关资源
    最近更新 更多