【发布时间】:2015-09-03 05:17:43
【问题描述】:
以下程序会产生诊断错误。
#include <memory>
class Containing {
// class Nested; // [1]: This line seems required.
typedef std::shared_ptr<class Nested> Ptr;
class Nested {
Ptr & ptr ();
void foo (const Ptr &p) {
p->ptr() = ptr()->ptr(); // [2]: Error here without [1]
}
};
};
int main () {}
生成的诊断是:
prog.cpp:8:14: error: invalid use of incomplete type 'class Nested' p->ptr() = ptr()->ptr(); ^ prog.cpp:4:35: error: forward declaration of 'class Nested'` typedef std::shared_ptr<class Nested> Ptr; ^
但是,如果我取消注释前向声明,则编译成功。我相信原因是Nested 在用于shared_ptr<> 时被假定为没有嵌套。如果是这样,是否有一种语法可以让shared_ptr<> 知道Nested 是嵌套的而没有前向声明?比如:
class Containing {
typedef std::shared_ptr<class Containing::Nested> Ptr;
//...
这个问题使用一个最小的例子来说明问题。实际结构如下:
class Containing {
typedef std::shared_ptr<class NestedInterface> Ptr;
class NestedObject {
Ptr ptr_;
//...
};
class NestedInterface {
virtual NestedObject & object () = 0;
void foo (const Ptr &p) {
// ...
}
//...
};
class NestedType1 : NestedInterface {
NestedObject obj_;
NestedObject & object () { return obj_; }
//...
};
class NestedType2 : NestedInterface {
Containing &c_;
NestedObject & object () { return c_.nested_object_; }
//...
};
//...
【问题讨论】:
-
一种替代方法是将 typedef 行移动到“class Nested {}”块的末尾...当然,您将无法再在该块中使用 typedef ,因此您需要在方法参数中明确指定基础类型(“std::shared_ptr
”)。 -
如果您只打算在
Nested的范围内使用Ptr,我相信您也可以将typedef in 放在Nested定义中。当然是compiles. -
生成激发问题的示例不会再使示例最小化。所有问题都必须充分激发吗?
-
那么为什么不公开
Nested的Ptrtypedef,如果你在Nested类中 typedef 它呢?我假设您想使用Ptr是有原因的,而不是表明Ptr指向 to? 的东西 -
除非使用class-key identifier;语法,在elaborated-type-specifier中首先声明的类总是introduced in a namespace or block scope , 而不是类作用域。
标签: c++ c++11 nested forward-declaration