c++中声明对象和使用类型定义的顺序
The order in which to declare objects and using typedef in C++
考虑一个类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,最后是类型定义,我得到的错误是container1, container2没有命名类型——类型在类声明时不存在;
首先是typepedef: loads of errors——类和结构都还没有定义;
- 首先声明类,并在public:节中定义该结构体的类型;错误指出第三个模板参数(C)无效——它尚未定义;
- 首先声明结构:错误表示类尚未定义。
我使用的方法是否不必要地麻烦,是否存在更优雅的解决方案?
重要警告: std::vector
等标准库容器在技术上不支持不完整类型。用不完整类型实例化它们是未定义的行为。在A
的定义中,A
类型是不完整的,这意味着你不能可靠地使用,例如,在A
的定义中,std::vector<A>
类型的成员。因此,您可能希望使用Boost的容器之类的东西来保证对不完整类型的支持。
下面的讨论假设B
和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;
定义type
只需要前向声明A
、vector
、B
和C
。typedef本身不会触发模板的实例化。
class A{
public:
type container1, container2;
};
这会触发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;
}
注意,你需要在a中创建一个compare_variable
成员。
你想要这样的东西吗?
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;
}
- 有没有一种方法可以通过"typedef"为重新定义的基本类型定义特征和强制转换运算符
- 强枚举类型定义:Clang Bug 还是 C++11 标准不确定性?
- 列表参数的类型定义
- 使用模板化的键类型定义 std::map,该键类型基于作为参数接收的函数
- 关于 C++ 中的函数类型定义
- C++(和 ROS) - 包含与前向声明引用,设置默认值和类型定义
- 将使用/类型定义限制为类范围
- 模板类型定义?
- C++:模板类的类型定义
- 如何对命名空间限定类型进行类型定义?
- 此递归模板类型定义是否有效C++?
- 具有调整对齐方式的类型定义
- C++从抽象类型定义类成员
- 用于C++代码的 API 监视器类型定义 (XML)
- 如何将result_of与函数类型定义一起使用
- 在C++的适当类型定义位置
- 如何根据模板类型定义浮点常量?
- 如何为缺少预定义运算符而不扩展命名空间"std"的标准类型定义运算符>> (istream &, ...)?
- 参数化类的别名(或类型定义)内部类
- 如果我想从类型"T"定义元素的容器(来自 STL),那么"T"必须使用默认构造函数?