有没有办法声明指向不完整类型的指针,该指针将由实现中的typedef设置?
这是我想要的例子:
#ifndef TEST_H
#define TEST_H
namespace std {
class string; // THIS WON'T WORK!
}
struct Test {
std::string *value;
};
#endif
string是basic_string的typedef,因此示例中的代码不起作用。我可以声明一个不完整类型的std :: basic_string,但这看起来像是一种解决方法。
我知道编译器不会为typedef生成符号,并且可能会在typedef中为不同文件中的不同类型使用相同的名称。但由于指针是指针(至少对编译器而言),因此应该可以做类似的事情。
编辑:这只是一个极简主义的工作例子。在我真正的问题中,我有一个Facade,它使用一个只有Facade应该知道的库中的类(不,它不是std :: string,而且库不是stl)。我并不是真的担心循环包含,但由于我的项目中的很多文件包括这个Facade(直接或间接),我担心编译时间,所以我想只将库文件包含在Facade的实现文件中。
答案 0 :(得分:5)
不,不是。
真的,在这一点上,你只需要#include <string>
。它没有害处,因为你不能与string
有循环依赖:标准标题甚至不知道你的标题存在!
无论如何,std::string*
通常是错误的。
答案 1 :(得分:3)
转发声明std::string
可能如下所示:
namespace std
{
template <class T, class Traits, class Allocator>
class basic_string;
template <class T>
class char_traits;
template <class T>
class allocator;
typedef basic_string<char, char_traits<char>, allocator<char> > string;
}
(这不会尝试转发声明basic_string
具有默认模板参数。由于这些只能被声明一次,我怀疑只有库作者可能有足够的控制权才能将其关闭。)
至于质疑std::string*
的用法,我想没有人会动态分配它们。但是,想要在别处引用其他字符串(或NULL)是不是有效?
答案 2 :(得分:1)
在({1}}中声明内容(主要)未定义。引用标准库对象,函数或类型的唯一合法方法是在包含相关标头之后。 17.4.3.1这样说。