为什么这是C ++中的前向声明? [英] Why is this a forward declaration in C++?

查看:65
本文介绍了为什么这是C ++中的前向声明?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在utilA.cpp中,我将具有以下代码段:

I will have the following code snippet in utilA.cpp:

// utilB.h
namespace xm
{
     void zoo(struct tm timeval);  //<-----line 0
}


// utilA.cpp
#include <utilB.h>                 //<----line 1
#include <time.h>                  //<----line 2
namespace xm
{
     void foo()
     {
         struct tm time1 = {0};    //<----line 3
     }
}

GCC在编译utilA.cpp时抱怨

GCC complains when compiling utilA.cpp,

error: variable 'xm::tm time1' has initializer but incomplete type

这似乎是因为 utilA.h 在第0行中使用了 struct tm ,但没有包含 time.h ,并且编译器将第0行中的 struct tm 视为前向声明,因此第2行中的 struct tm 被解析为内部的 xm :: tm 标题位于第0行.

It seems this is because the utilA.h is using struct tm in line 0, but without include the time.h, and the compiler treat the struct tm in line 0 as a forward declare, so the struct tm at line 2 is resolved as xm::tm inside the header at line 0.

那么C ++标准是否将此 struct tm 定义为作为前向声明的函数参数类型?请帮忙解释一下,标准中的引号会有所帮助.

So does the C++ standard define this struct tm as an type of function parameter as forward declaration? Please help to explain this and quotes from the standard will helpful.

推荐答案

在第0行中,您在 xm 名称空间内声明了一个名为 tm 的类.是的,C ++允许在函数/模板参数中声明类型.

In line 0, you declared a class named tm inside the xm namespace. Yes, C++ allows declaring types in function/template parameters.

N4140§3.4.4 [basic.lookup.elab]/2

N4140 § 3.4.4 [basic.lookup.elab]/2

如果 class-key 引入了精心设计的类型说明符,并且此查询找不到先前声明的 type-name ,或者 elaborated-type-specifier 出现在声明中,格式为:

If the elaborated-type-specifier is introduced by the class-key and this lookup does not find a previously declared type-name, or if the elaborated-type-specifier appears in a declaration with the form:

class-key attribute-specifier-seq opt 标识符;

class-key attribute-specifier-seqopt identifier;

修饰类型说明符是一个声明,其中引入了类别名称,如3.3.2中所述.

the elaborated-type-specifier is a declaration that introduces the class-name as described in 3.3.2.

因为您在 xm 命名空间内声明了一个名为 tm 的类,所以它是名称查找在第3行中为 tm 找到的名字.不考虑 :: tm (和 :: std :: tm ).而且,由于没有对类 :: xm :: tm 的定义,因此编译器会抱怨它是不完整的类型.

Because you declared a class named tm inside the xm namespace, it's the first name that name lookup finds for tm in line 3. ::tm (and ::std::tm) are not considered. And since there's no definition of class ::xm::tm, the compiler complains about it being an incomplete type.

如果您不是用C ++编写C代码,则会编写类似 1

If you weren't writing C code in C++, you'd write something like1

struct tm;

namespace xz{
    void zoo(tm timeval);
}

#include <ctime>

namespace xz{
    void zoo(tm timeval);
}

,您将不会遇到这个问题.

and you wouldn't have that problem.

1 请记住,您无法在名称空间std中转发声明名称

这篇关于为什么这是C ++中的前向声明?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆