未在范围中声明 - priority_queue C ++的友元比较器类

时间:2016-06-03 07:31:47

标签: c++ templates stl priority-queue friend

首先让我压缩相关代码,注意产生错误的参数movies

// ActorGraph.hpp
class ActorGraph
{
protected:
    class Movie; // definition further below
    friend class MovieYearComparator;

    int func(..., priority_queue<Movie, vector<Movie>, MovieYearComparator> &movies);

    class Movie {...};
};

在实施文件中,我们有:

// ActorGraph.cpp
class MovieYearComparator
{
public:
    bool operator() (const ActorGraph::Movie a, const ActorGraph::Movie b) const
    {
        // comparison operation
    }
};

ActorGraph::func(..., priority_queue<Movie, vector<Movie>, MovieYearComparator> &movies) 
{...}

但是,g ++抱怨MovieYearComparator 未在此范围内声明,引用func声明。我正确地拼写了一切,这个范例适用于文件中的其他容器,而不是优先级队列。请注意Movie是一个非常小的类,因此我选择按值传递它。

1 个答案:

答案 0 :(得分:3)

当你转发声明一个类时,你不能用它做任何事情,你只有权使用/存储引用或指向它,例如:

struct A;

struct B {
    A *_a; // Ok
    B (A &a) : _a(&a) { } // Ok
};

void f (A a) { } // Oops!

原因很简单:如果您不使用引用或指针,编译器必须在使用时知道struct / class的大小。< / p>

在您的情况下,priority_queue需要使用Comparer的非引用,但自从您第一次实例化模板(在ActorGraph的定义中)以来{{1} (Comparer)不是完整类型,MovieYearComparator无法实例化。

您需要在priority_queue的第一次实例化之前定义 MovieYearComparator类,例如:

priority_queue

如果你想让你的标题“干净”,你只能在标题中定义类,但在cpp文件中实现class ActorGraph { protected: class Movie; // definition further below class MovieYearComparator { public: // Use reference since your forward-declare Movie bool operator() (const ActorGraph::Movie const& a, const ActorGraph::Movie const& b) const { // comparison operation } }; int func(..., priority_queue<Movie, vector<Movie>, MovieYearComparator> &movies); class Movie {...}; };

operator()

另请注意,由于class ActorGraph { protected: class Movie; // definition further below struct MovieYearComparator { bool operator() (const ActorGraph::Movie const& a, const ActorGraph::Movie const& b) const; }; int func(..., priority_queue<Movie, vector<Movie>, MovieYearComparator> &movies); class Movie {...}; }; // .cpp bool ActorGraph::MovieYearComparator::operator() (const ActorGraph::Movie const& a, const ActorGraph::Movie const& b) const { } 现在是MovieYearComparator的内部类,因此您无需将其设为朋友类。