2011-07-25 16 views
10

にプライベートメンバーに達することができないコードを検討してください:C++グローバルにextern "C" の友人は、名前空間、クラス

#include <iostream> 

using namespace std; 

extern "C" 
void foo(void); 

namespace A 
{ 
    template< int No > 
    class Bar 
    { 
    private: 
     friend void ::foo(void); 

     static void private_func(int n); 
    }; 

    template< int No > 
    void Bar<No>::private_func(int n) 
    { 
     cout << "A:Bar< " << No << ">::private_func(" << n << ")" << endl; 
    } 
} 

extern "C" 
void foo(void) 
{ 
    A::Bar<0>::private_func(1); 
} 

int main() 
{ 
    cout << " ---- " << endl; 
    foo(); 
} 

G ++が与える:

> g++ -Wall -o extern_c extern_c.cpp 
extern_c.cpp: In function ‘void foo()’: 
extern_c.cpp:20:7: error: ‘static void A::Bar<No>::private_func(int) [with int No = 0]’ is private 
extern_c.cpp:29:31: error: within this context 

私はnamspace Aコメントした場合、それがコンパイルされます正しく実行してください。

私には何が欠けていますか?

私は関連トピックを見ましたが、私の問題に合ったものは見つかりませんでした。

おかげで人々。


EDIT:

私は今extern "C"が問題とは何の関係もないと確信しています。 無視してください。

答えて

2

私は説明は分かりませんが、foo()を名前空間に入れると、それが動作します。

#include <iostream> 

using namespace std; 

namespace C 
{ 
    extern "C" 
    void foo(void); 
} 

namespace A 
{ 
    template< int No > 
    class Bar 
    { 
    private: 
     friend void C::foo(void); 

     static void private_func(int n); 
    }; 

    template< int No > 
    void Bar<No>::private_func(int n) 
    { 
     cout << "A::Bar< " << No << ">::private_func(" << n << ")" << endl; 
    } 
} 


namespace C 
{ 
    extern "C" 
    void foo(void) 
    { 
     A::Bar<0>::private_func(1); 
    } 
} 

int main() 
{ 
    cout << " ---- " << endl; 
    C::foo(); 
} 

そして結果:

[email protected] friends]$ g++ -Wall namespace_friend.cpp -o namespace_friend 
[[email protected] friends]$ ./namespace_friend 
---- 
A::Bar< 0>::private_func(1) 
+0

実際の 'foo()'を名前空間に入れるのは簡単ではありません。なぜなら、それは割り込みサービスルーチンなので、とにかく試してみるつもりです。ありがとう。 – j4x

+1

私はこの男が同じ問題を抱えていると思いますが、どちらも答えられていません:http://stackoverflow.com/questions/2236712/how-do-i-define-a-friend-class-from-the-global-namespace- in-another-namespace –

+0

同じ問題があるようですが、空の名前空間の提案は機能しません。同じエラーが表示されます。 – j4x

0

友人をextern "C"と宣言する必要があります。あなたの現在の友人宣言は、C++の名前のマングリングを持つグローバル名前空間で友人fooを見つけます。

+0

正確な構文は何ですか? –

+0

O-ho。 14行目を 'friend extern" C "void :: foo(void);に変更すると、' extern_c.cpp:14:22:error:文字列定数の前にunqualified-idが予想されます。 – j4x

4

g ++バグです。 4.4で存在し、4.6で固定されています。

UPD:templatenamespaceの組み合わせによってトリガーされているようです。 extern "C"はコメントになる可能性があり、エラーが残ります。

+0

あなたは参照を引用できますか? –

+0

'g ++(SUSE Linux)4.5.1 20101208 [gcc-4_5ブランチリビジョン167585]'。私は4.6を検索し、それが動作するかどうかを伝えます。 – j4x

+0

@マークB:C++標準では、名前空間に囲まれたクラステンプレートの場合、友人の宣言を静かに無視してはならないとは思われません。私はそれを行うコンパイラが間違っていなければならないと結論づけます。おそらく標準全体を引用することを除いて、私はそれを証明することはできません。 –

関連する問題