33

偶然、私が見ていたソースコードの1つでこれを見つけました。だから、私はここで同様の小さな例を挙げています。

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 ++標準には、スコープを解決する必要がない場合、スコープ解決演算子は無視されるという何かがありますか?

4

2 に答える 2

42

このコードは無効です。

コードを受け入れるのはg++のバグでした。「g++は注入されたクラス名を正しく処理しない」を参照してください。 このバグは2009年に修正されたように解決されたため、最近のバージョンのg++で修正する必要があります。

于 2012-04-07T01:19:47.070 に答える
16

§9/2で指定されているように、状況を明確にするために:

クラス名は、クラス名が表示された直後に宣言されているスコープに挿入されます。クラス名は、クラス自体のスコープにも挿入されます。これは、注入されたクラス名として知られています。アクセスチェックの目的で、注入されたクラス名は、パブリックメンバー名であるかのように扱われます。

ただし、§3.4.3.1/ 1で指定されているように:

修飾IDのネストされた名前指定子がクラスを指定する場合、以下にリストされている場合を除いて、ネストされた名前指定子の後に指定された名前がクラス(10.2)のスコープで検索されます。

[...§3.4.3.1/2]:

コンストラクターが受け入れ可能なルックアップ結果であり、nested-name-specifierがクラス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
于 2012-04-07T01:29:22.007 に答える