未在范围内声明 - priority_queue C++ 的朋友比较器 class
Not declared in scope - friend comparator class for priority_queue C++
先把相关代码压缩一下,注意产生错误的参数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
是一个非常小的 class,因此我选择按值传递它。
当你forward-declare一个class时,你不能用它做任何事情,你只有使用/存储引用或指向它的指针的权利,例如:
struct A;
struct B {
A *_a; // Ok
B (A &a) : _a(&a) { } // Ok
};
void f (A a) { } // Oops!
原因很简单:如果不使用引用或指针,编译器必须知道struct
/class
的大小使用时
在你的例子中,priority_queue
需要使用Comparer
的non-reference,但是由于你第一次实例化模板(在ActorGraph
的定义中)你的Comparer
(MovieYearComparator
)不是完整类型,priority_queue
无法实例化
您需要在 priority_queue
的第一个实例化之前 定义 MovieYearComparator
class,例如:
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 {...};
};
如果你想保留你的 header "clean",你只能在 header 中定义 class 但在 cpp 中实现 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
现在是 ActorGraph
的内部 class,您无需将其设为好友 class。
先把相关代码压缩一下,注意产生错误的参数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
是一个非常小的 class,因此我选择按值传递它。
当你forward-declare一个class时,你不能用它做任何事情,你只有使用/存储引用或指向它的指针的权利,例如:
struct A;
struct B {
A *_a; // Ok
B (A &a) : _a(&a) { } // Ok
};
void f (A a) { } // Oops!
原因很简单:如果不使用引用或指针,编译器必须知道struct
/class
的大小使用时
在你的例子中,priority_queue
需要使用Comparer
的non-reference,但是由于你第一次实例化模板(在ActorGraph
的定义中)你的Comparer
(MovieYearComparator
)不是完整类型,priority_queue
无法实例化
您需要在 priority_queue
的第一个实例化之前 定义 MovieYearComparator
class,例如:
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 {...};
};
如果你想保留你的 header "clean",你只能在 header 中定义 class 但在 cpp 中实现 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
现在是 ActorGraph
的内部 class,您无需将其设为好友 class。