2013-03-28 88 views
5

以下(LiveWorkspace here)被GCC 4.7.2,GCC 4.8.0和ICC 13.0.1拒絕。通過使用聲明對朋友功能是否合法?

namespace A { 
    namespace B { 
     void C(); 
    } 
    using B::C; 
} 

class D { 
    friend void A::C(); 
}; 

此外,它崩潰鐺3.2(!)。我已經提交了一個bug報告,並且已經提供了patch的崩潰問題,但是我不能100%確定這段代碼是否真的出錯,因爲我找不到§7.3.3[namespace.udecl]§11.3[class.friend]明確地說明了這種情況,但也許在我錯過的各種名稱說明符術語之一的定義中有某些東西。

而且,好像所有的四個編譯器接受以下(LiveWorkspace here)

namespace A { 
    namespace B { 
     class C; 
    } 
    using B::C; 
} 

class D { 
    friend class A::C; 
}; 

似乎有不被任何有關這兩種情況根本不同的,所以我很好奇GCC和ICC的理由如果有的話,拒絕第一個例子但不是這個例子。更熟悉標準的人能找到解決這個問題的任何東西嗎?

這絕對是一個小問題,在最好的,但因爲我修補它,我想,以確保我在做正確的事...

編輯This is patched now in clang/trunk!

新的編輯:下面約翰內斯的回答解釋了爲什麼我原來的例子被拒絕,但它似乎並沒有解釋爲什麼GCC和ICC也拒絕以下(LiveWorkspace here)

namespace A { 
    namespace B { 
     void C(); 
    } 
    using B::C; 

    class D { 
     friend void C(); 
    }; 
} 

回答

4

8.3p1:

當聲明符-id爲合格, 聲明應指類或命名空間,其限定詞 指的先前聲明的構件(或者,在一個命名空間的情況下, (7.3.1)) 的內聯命名空間集合的元素或其專業化; 該成員不僅僅是由聲明者ID的嵌套名稱說明者指定的類或名稱空間範圍內的使用聲明 引入的。

一個class foo;class foo::bar;不包含聲明符-ID,所以它不受此規則。相反,foo::bar是詳細說明類型說明符(7.1.6.3)的一部分。

+0

那麼爲什麼類的版本可以嗎? –

+0

好吧,+1,對我來說很有意義。好東西,否則這將需要更多的努力來解決:D –

+0

但我不知道的理由。這就是規則出現在規範中的地方。如果這能幫助你,我很高興。 –