【问题标题】:Pointer to a typedef with incomplete type指向类型不完整的 typedef 的指针
【发布时间】:2011-07-22 23:09:37
【问题描述】:

有没有办法声明一个指向不完整类型的指针,该类型将由实现中的 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 的实现文件中。

【问题讨论】:

  • 许多编译器提供了一个<stringfwd>,它提供了一个工作前向声明。

标签: c++


【解决方案1】:

不,不是。

真的,在这一点上,您只需要#include <string>。这没有害处,因为您不能与 string 建立循环依赖关系:标准标头甚至不知道您的标头存在!

无论如何,std::string* 通常是错误的。

【讨论】:

  • 我同意 std::string* 通常是错误的,但这只是一个极简主义的工作示例。
  • 它也应该有意义,否则它并没有真正表现出任何东西。无论如何...
  • 好的,我编辑了我的问题,添加了有关实际问题的更多信息。
【解决方案2】:

转发声明 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;
}

Example.

(这不会尝试转发声明 basic_string 具有默认模板参数。由于这些只能声明一次,我怀疑只有库作者可能有足够的控制权来实现它。)


至于质疑std::string*的用法,我猜没有人会动态分配它们。但是,想在其他地方引用其他字符串(或 NULL)是否有效?

【讨论】:

    【解决方案3】:

    namespace std 中声明的东西(大部分)是未定义的。引用标准库对象、函数或类型的唯一合法方式是在包含相关标头之后。 17.4.3.1 这么说。

    【讨论】:

      猜你喜欢
      • 2017-02-25
      • 1970-01-01
      • 2016-09-05
      • 2021-09-01
      • 2011-09-10
      • 2020-04-30
      • 2021-12-31
      • 2012-08-15
      相关资源
      最近更新 更多