繁体   English   中英

在名称空间中转发定义类?

[英]Forward defining class in namespace?

以下代码段无法使用Visual Studio 2010进行编译,但GCC喜欢它:

namespace Test { 
    class Baz;
    // Adding class Bar; here and removing the class below makes it work
    // with VC++, but it should work like this, shouldn't it?
    void Foo (Baz& b, class Bar& c);
}

namespace Test { 
    class Bar
    {
        // Making this method non-template works
        template <typename T>
        static void Lalala ()
        {
        }
    };
}

int main ()
{
}

我在这里做些蠢事还是这是一个有效的编译器错误? 我得到的错误是: error C2888: 'void Bar::Foo(void)' : symbol cannot be defined within namespace 'Test'

它汇编了GCC 4.5.1: http//ideone.com/7sImY

[编辑]为了清楚起见,我想知道这是否是有效的C ++(如果是这样,为什么不呢) - 编译它的变通方法很好但不是这个问题的一部分。

好吧,我也在 codepad.org中尝试了它并编译,但我不确定它应该(不精通C ++编译器功能)!

解决方法:转发声明Bar也可以在制作Foo之前定义Bar 换句话说,这在MSVC中编译:

namespace Test 
{ 
    class Baz;
    class Bar;// also forward-declare Bar
    void Foo (Baz& b, class Bar& c);
}

namespace Test 
{ 
    class Bar
    {
        template <typename T>
        static void Foo ()
        {
        }
    };
}

int main(void)
{

    return 0;
}

更新:我认为这可能已经是一个向微软报告的错误...这看起来非常接近: http//connect.microsoft.com/VisualStudio/feedback/details/99218/invalid-error-c2888-when-a-类的定义类后它,是申报

微软引用的解决方法:

A stand-alone forward declaration consists of an elaborated type specifier followed by a semicolon.

insert the declaration

class C2888;

before the declaration of foo(C2888o, C2888). 

可能是编译错误。

更改参数的顺序将更改编译结果。

namespace Test { 
void Foo (class Bar& b, class Baz& c) - will compile.
}

我认为代码格式正确。 但事实证明,要确保标准中没有任何内容与使用相矛盾。

C ++ 11标准中的一些相关引用:

3.3.2 p6:

详细说明的类型说明符中首先声明的类的声明点如下:

  • 表单类密钥标识符详细类型说明
    • 如果在命名空间作用域中定义的函数的decl-specifier-seqparameter-declaration-clause中使用了elaborated-type-specifier,则在包含声明的命名空间中将标识符声明为类名 否则,除了作为友元声明之外, 标识符在包含声明的最小的非类非函数原型范围中声明。

3.4.4 p2:

如果elaborated-type-specifier没有嵌套名称说明符 ,并且除非elaborated-type-specifier出现在具有以下形式的声明中: class-key attribute-specifier-seq opt identifier ; 根据3.4.1查找标识符 ,但忽略已声明的任何非类型名称。 ...如果class-key引入了elaborated-type-specifier ,并且此查找未找到先前声明的类型名称 ,或者如果elaborated-type-specifier出现在具有以下形式的声明中: class-key属性-specifier-seq opt identifier ; elaborated-type-specifier是一个声明 ,它引入了3.3.2中描述的类名

7.1.6有一些语法定义确定一个详细类型说明符在语法上可以是一个类型说明符 7.1确定类型说明符在语法上可以是一个decl-specifier ,它是在函数参数声明 (8.3.5)中用作类型的语法单元。

class Bar构造是错误的。 你是不是一个没有使用过typedef struct { /* members */ } Foo的C程序员?

Anywho,你需要在测试中定义Bar和Baz:

namespace Test {
    class Bar;
    class Baz;
};

并在声明函数参数时删除classstructunionenum关键字。

通过这种修改,它可以在g ++ 4.6中完全编译。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM