Mus*_*edi 3 c++ typedef predicate declaration
考虑一个类A,STL容器B和容器的二元谓词C.
容器B在类A中使用.但是类A也用在二元谓词C中.
struct C{
bool operator()(A const &a, A const &b){
return a.compare_variable < b.compare_variable;
}
};
Run Code Online (Sandbox Code Playgroud)
我们需要这个谓词来定义容器,它使用它来对元素进行排序.
因为容器声明变得相当长,所以我使用typedef来简化声明.
typedef B<A, vector<A>, C> type;
Run Code Online (Sandbox Code Playgroud)
最后,我的目标是在类A中声明容器B ---其声明缩写为"type"---即,作为静态公共成员变量.
class A{
public:
type container1, container2;
};
Run Code Online (Sandbox Code Playgroud)
什么是正确的顺序是宣布A,B和C?
我按顺序尝试了以下变化:
首先声明类A,然后是结构C,最后是typedef,我得到容器1,容器2没有命名类型的错误---类声明在类声明时不存在;
首先是typedef:错误加载---类和结构都没有定义;
我使用的方法是不必要的麻烦,是否存在更优雅的解决方案?
重要警告:标准库容器在std::vector技术上不支持不完整类型.使用不完整类型实例化它们是未定义的行为.类型A在定义中是不完整的A,这意味着您无法可靠地使用,例如,std::vector<A>定义中的类型成员A.因此,您希望使用类似Boost容器之一的东西来保证对不完整类型的支持.
以下讨论假定B并vector支持不完整类型的实例化.如果他们不这样做,就不可能做你想做的事.
首先,找出依赖关系:
struct C {
bool operator()(A const &a, A const &b){
return a.compare_variable < b.compare_variable;
}
};
Run Code Online (Sandbox Code Playgroud)
定义C自己,包括声明 C::operator(),只需要A向前宣布.但是,定义 C::operator()需要完整定义A,因为函数体引用了一个成员A.
typedef B<A, vector<A>, C> type;
Run Code Online (Sandbox Code Playgroud)
定义type仅需要A,vector和B,以及C向前声明.typedef本身不会触发模板的实例化.
class A{
public:
type container1, container2;
};
Run Code Online (Sandbox Code Playgroud)
这会触发实例化B<A, vector<A>, C>,需要完整定义B.容器可能还需要C比较器作为完整类型,因为它们需要存储它的副本.
简而言之:
C需要前向声明A.定义C::operator()需要完整的定义A.type需要前向声明A,B和C.A需要的完整定义B和C.一旦整理了依赖项,就可以编写代码了.假设B通过包含适当的头来定义:
class A; // Forward declare A for C's definition
struct C {
bool operator()(A const &a, A const &b);
};
typedef B<A, vector<A>, C> type;
class A{
public:
type container1, container2;
};
inline bool C::operator()(A const &a, A const &b){
return a.compare_variable < b.compare_variable;
}
Run Code Online (Sandbox Code Playgroud)
请注意compare_variable,显然你需要在A中实际成为一个成员.