声明对象并在C中使用typedef的顺序
考虑一个类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没有命名类型的错误—在类声明时类型不存在; 我使用的方法是不必要的麻烦,是否存在更优雅的解决方案? 解决方法
重要警告:标准库容器如std :: vector技术上是
do not support incomplete types.使用不完整类型实例化它们是未定义的行为.类型A在A的定义中是不完整的,这意味着您不能可靠地使用例如std :: vector< A>类型的成员.在A的定义中.因此,你想要使用像
one of Boost’s containers那样保证支持不完整类型的东西.
以下讨论假定B和向量支持具有不完整类型的实例化.如果他们不这样做,就不可能做你想做的事. 首先,找出依赖关系: 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,C> type; 定义类型仅需要向前声明A,向量,B和C. typedef本身不会触发模板的实例化. class A{ public: type container1,container2; }; 这触发了B< A,vector< A>,C>的实例化,需要B的完整定义.容器可能还需要C(比较器)是完整类型,因为它们需要存储它的副本. 简而言之: >定义C需要A的前向声明.定义C :: operator()需要A的完整定义. 一旦整理了依赖项,就可以编写代码了.假设B通过包含适当的头来定义: class A; // Forward declare A for C's definition struct C { bool operator()(A const &a,A const &b); }; typedef B<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; } 请注意,您需要在A中实际创建一个compare_variable成员. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |