【问题标题】:Why is forward declaration of a class which will be a typedef not allowed?为什么不允许前向声明将是 typedef 的类?
【发布时间】:2011-06-22 10:09:50
【问题描述】:

如果我想使用一个指向类的指针并且我不对它做任何操作,我们可以转发声明这个类。但是,如果这恰好是 typedef,为什么不允许呢? 在下面的例子中,它只编译了我包含注释的代码,但为什么编译器想知道它呢?我如何转发声明可能是 typedef 的东西。在 c++0x 中这种行为有什么变化吗?

#include <iostream>
using namespace std;
/*
template<class T>
class temp;

typedef temp<int> later;
*/
class later;
void somefunc(later*);
int main()
{
  later* l;
  somefunc(l);
  return 0;
}
//The following is in someother file/compilation unit.
template<class T>
struct temp
{
  public:
    void print()
    {
        T t(5);
        std::cout<< "helloworld: " << t << std::endl;
    }
};
typedef temp<int> later;
void somefunc(later* l)
{
  l = new later();
  l->print();
}

【问题讨论】:

    标签: c++ c++11 typedef forward-declaration


    【解决方案1】:

    typedef 不会创建类型,它只是将新名称添加到现有类型,并且您不能转发声明它。我建议您阅读此answer 以了解其他相关问题,我认为它有助于理解 typedef 和用户定义类型的声明之间的区别。

    另一方面,您可以前向声明实际类型,然后在适当位置添加 typedef。

    编辑:扩展您的特定示例:

    在声明temp 模板后,标识符temp 在用户定义类型标识符空间中可用(与符号的其余标识符空间不同)。 typedef 将通过名称later 在全局标识符空间中创建一个别名,因此在注释行之后(如果它们未注释),用户定义类型标识符空间将包含引用模板的temp,标识符@驻留在全局标识符空间中的 987654326@ 将引用具体实例化temp&lt;int&gt;。 (真是满嘴的“标识符”和“空格”!)

    另一方面,如果您在第一个未注释行class later; 中转发声明该类,您所做的是向用户定义类型标识符空间添加一个标识符。可以在以下示例中看到差异:

    class A;           // Creates A identifier only in user defined types space
    typedef int B;     // Creates B identifier in the global identifier space
    
    void A(){}         // Ok: A will refer to void A(); class A will refer to the type
    //void B(){}       // Error: B symbol collides with the typedef
    

    【讨论】:

    • 是的,我明白这一点,但为什么会这样?然而,它最终会指向一个类型。不破坏前向声明的使用吗?
    • @balki: 确实如此:/ 例如,大多数人会#include &lt;string&gt; 而不是走很长的路并向前声明std::basic_string
    • @balki:我添加了一个指向另一个问题的答案的链接,其中解释了typedef 的语义。最初的问题是 C,但它适用于此处,并且答案包含一些 C++ 内容。基本上,用户定义的类型声明将类型(以及可能引用它的标识符)添加到用户定义的标识符空间,而typedef 在引用给定类型的不同标识符空间中创建标识符。
    • @Matthieu:您不能转发声明 std::basic_string。
    • @Fanael: 你可以template&lt;typename, typename, typename&gt; class basic_string; 物理上,你是否被允许的问题?
    猜你喜欢
    • 1970-01-01
    • 2014-12-02
    • 1970-01-01
    • 1970-01-01
    • 2016-06-19
    • 1970-01-01
    • 1970-01-01
    • 2018-01-12
    • 2018-08-15
    相关资源
    最近更新 更多