【问题标题】:Scope resolution operator范围解析运算符
【发布时间】:2012-04-20 12:10:09
【问题描述】:

我偶然在我正在查看的一个源代码中发现了这一点。所以,我在这里给出一个类似的小例子。

在文件test.h中:

#include<iostream>

class test{
    int i;
public:
    test(){}
    //More functions here
};

在文件test.cpp中:

#include "test.h"

int main()
{
    test test1;
    test::test test2;
    test::test::test test3;
    return 0;
}

首先,有理由这样声明test2吗?其次,这段代码在 g++ 4.4.3 及更低版本中编译得很好。 C++ 标准中有没有说,当不需要解析作用域时,作用域解析运算符会被忽略?

【问题讨论】:

    标签: c++ scope g++


    【解决方案1】:

    为了澄清情况,如 §9/2 中所述:

    在看到类名后立即将类名插入到声明它的作用域中。类名也被插入到类本身的范围内;这被称为注入类名。出于访问检查的目的,注入的类名被视为公共成员名。

    但是,如 §3.4.3.1/1 中所述:

    如果限定 ID 的嵌套名称说明符指定了一个类,则在该类 (10.2) 的范围内查找嵌套名称说明符之后指定的名称,但下面列出的情况除外。

    [...§3.4.3.1/2]:

    在构造函数是可接受的查找结果且嵌套名称说明符指定类 C 的查找中:

    ——如果在嵌套名称说明符之后指定的名称,当在 C 中查找时,是 C 的注入类名称(第 9 条)[...],则该名称被视为命名构造函数C类。

    [ ... 示例:]

    struct A { A(); };
    [ ... ]
    A::A a; // error, A::A is not a type name
    struct A::A a2; // object of type A
    

    【讨论】:

      【解决方案2】:

      此代码无效。

      它接受代码是 g++ 中的一个错误。请参阅"g++ does not treat injected class name correctly." 该错误已在 2009 年修复,因此它应该在任何最新版本的 g++ 中修复。

      【讨论】:

      • 奇怪的事情:Ideone 编译这段代码:ideone.com/Duwzy 他们使用的是什么 GCC?
      • @kralyk:是的。观察 ideone 使用 gcc 4.3.4 并观察如果你使用它的“C++0x”选项编译,它使用 gcc 4.5.1,代码被拒绝。
      • @Ashwin :您的问题说它与 4.4.3 编译得很好。 ;-]
      • 哦,我的意思是 4.4.3 之后的版本 :-)
      猜你喜欢
      • 2010-09-09
      • 2014-10-05
      • 2015-12-18
      • 2018-04-24
      • 1970-01-01
      • 2013-06-13
      • 2011-05-09
      • 2011-07-28
      • 2017-04-07
      相关资源
      最近更新 更多