在C ++中声明对象和使用typedef的顺序

时间:2014-07-20 17:47:01

标签: c++ typedef declaration predicate

考虑一个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;
  }
};

我们需要这个谓词来定义容器,它使用它来对元素进行排序。

因为容器声明变得相当长,所以我使用typedef来简化声明。

typedef B<A, vector<A>, C> type;

最后,我的目标是在类A中声明容器B ---其声明缩写为“type”---即,作为静态公共成员变量。

class A{
  public:
  type container1, container2;
};

什么是正确的顺序是声明A,B和C?

我按顺序尝试了以下变化:

  • 首先声明类A,然后是结构C,最后是typedef,我得到容器1,容器2没有命名类型的错误---类声明在类声明时不存在;

  • 首先是typedef:错误加载---类和结构都没有定义;

  • 首先声明类,在public中使用typedef:section结构:一个错误,说第三个模板参数(C)无效---它尚未定义;
  • 首先声明结构:错误说该类尚未定义。

我使用的方法是不必要的麻烦,是否存在更优雅的解决方案?

2 个答案:

答案 0 :(得分:6)

重要警告:标准库容器,例如std::vector技术上do not support incomplete types。使用不完整类型实例化它们是未定义的行为。类型AA的定义中不完整,这意味着您无法在{{1}的定义中可靠地使用类型std::vector<A>的成员}}。因此,您希望使用one of Boost's containers之类的内容来保证对不完整类型的支持。

以下讨论假设AB支持不完整类型的实例化。如果他们不这样做,就不可能做你正在尝试的事情要做。


首先,找出依赖关系:

vector

定义struct C { bool operator()(A const &a, A const &b){ return a.compare_variable < b.compare_variable; } }; 本身,包括声明 C,只需要C::operator()进行前向声明。但是,定义 A需要C::operator()的完整定义,因为函数体引用了A的成员。

A

定义typedef B<A, vector<A>, C> type; 只需要typeAvectorB进行前向声明。 typedef本身并不触发模板的实例化。

C

这会触发class A{ public: type container1, container2; }; 的实例化,需要B<A, vector<A>, C>的完整定义。容器可能还需要比较器B为完整类型,因为它们需要存储它的副本。

简而言之:

  • 定义C需要C的前瞻声明。定义A需要C::operator()的完整定义。
  • 定义A需要typeAB的前瞻声明。
  • 定义C需要AB的完整定义。

一旦您整理了依赖项,就可以编写代码。假设通过包含适当的标头来定义C

B

请注意,您需要在A中实际成为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; } 成员。

答案 1 :(得分:1)

所以你想要这样的东西?

class A {
  struct C{
    bool operator()(A const &, A const &);
  };
  typedef B<A, vector<A>, C> type;
  type c1, c2;

public:
  int compare_variable; // ?
};
// the definition below should either go in a .cpp file,
// or you should mark it inline
bool A::C::operator()(A const &x, A const &y) {
  return x.compare_variable < y.compare_variable;
}