为什么一个类的前向声明将是一个typedef是不允许的
Why is forward declaration of a class which will be a typedef not allowed?
如果我想使用一个指向类的指针,并且不对其进行任何操作,我们可以转发声明该类。但是,如果这恰好是一个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();
}
typedef不会创建类型,它只是在现有类型中添加一个新名称,并且不能转发声明它。我建议您阅读另一个相关问题的答案,我认为它有助于理解typedef和用户定义类型声明之间的差异。
另一方面,您可以正向声明实际类型,然后在适当的位置添加typedef。
编辑:扩展您的特定示例:
在声明temp
模板之后,标识符temp
在用户定义的类型标识符空间(与符号的标识符空间的其余部分不同)中可用。typedef将在全局标识符空间中以later
的名称创建一个别名,因此在注释行(如果它们未注释)之后,用户定义的类型标识符空间将包含引用模板的temp
,而驻留于全局标识符空间的标识符later
将引用具体实例化temp<int>
。(真是一口"标识符"answers"空间"!)
另一方面,如果像在第一行未注释的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
相关文章:
- 我们可以访问一个不存在的联盟的成员吗
- 为什么 Clang 不允许"and"作为函数名称?
- 不允许在向量中添加更多元素
- std::带有自定义缓冲区的 iostream 不允许我写入
- Visual Studio 2017 不允许我创建 C++ 专用模板
- 返回时不允许隐式转换
- 为什么 c++(g++) 不允许模板返回类型和函数名称之间有空格?
- 为什么 c++ 不允许(自动)强制转换?
- error dllimport 函数的定义不允许在一个特定的联合中,而其他类、结构和联合将按预期导出
- C++:为什么允许在另一个函数中声明函数,而不允许在函数定义中声明?
- 我在代码中有一个错误,错误是:(智能感知:不允许抽象类类型"HourlyWorker"的对象:)
- 为什么不允许将右值引用绑定到非常数引用,而允许在其中一个上调用非常数成员函数
- C++ 不允许我在以前工作后通过引用将 vector 传递给另一个函数
- 为什么gcc允许一个没有用户声明的默认构造函数的const对象,而不允许clang
- 如果对象没有默认构造函数,并且不允许在其类定义中创建一个,那么如何将对象放入节点中?
- 为什么c++不允许函数参数作为默认值使用后一个参数
- 为什么c++编译器允许将一个不能为constexpr的函数声明为constexpr ?
- 为什么一个类的前向声明将是一个typedef是不允许的
- 为什么 GCC 不允许我将模板参数用于另一个模板的参数?
- 每个结构只允许一个不允许大小的数组