2011-07-25 12 views
10

कोड पर विचार करें:सी ++ वैश्विक extern "सी" दोस्त namespaced वर्ग पर निजी सदस्य नहीं पहुँच सकते हैं

> 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, यह संकलन होगा:

#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(); 
} 

जी ++ देता है और सही ढंग से चलाएं।

मुझे क्या याद आ रही है?

मैंने संबंधित विषयों को देखा, लेकिन मेरी समस्या में कोई भी फिट नहीं मिला।

धन्यवाद लोग।


संपादित करें:

मैं अब आश्वस्त 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- इन-एंड-नेमस्पेस –

+0

यह एक ही समस्या प्रतीत होता है, लेकिन खाली नामस्थान सुझाव काम नहीं करता है। मुझे एक ही त्रुटि दिखाई देती है। – j4x

0

आपको मित्र को "सी" के रूप में घोषित करने की आवश्यकता है। आपके वर्तमान मित्र की घोषणा वैश्विक नामस्थान में एक दोस्त foo पाती है जिसमें सी ++ नाम मैंगलिंग है।

+0

सटीक सिंटैक्स क्या है? –

+0

ओ-हो। यदि मैं लाइन 14 को 'दोस्त बाहरी "सी" शून्य :: foo (शून्य) में बदलता हूं;' मुझे अतिरिक्त त्रुटि 'extern_c.cpp: 14: 22: त्रुटि: स्ट्रिंग स्थिर होने से पहले अयोग्यता-आईडी अपेक्षित है। – j4x

4

यह एक g ++ बग है। 4.4 में तय, 4.6 में तय किया गया।

यूपीडी: ऐसा लगता है कि यह template और namespace के संयोजन से ट्रिगर हुआ है। extern "C" प्रासंगिक नहीं है, क्योंकि इसकी टिप्पणी की जा सकती है और त्रुटि बनी हुई है।

+0

क्या आप एक संदर्भ उद्धृत कर सकते हैं? –

+0

'जी ++ (एसयूएसई लिनक्स) 4.5.1 20101208 [जीसीसी -4_5-शाखा संशोधन 167585]'। मैं 4.6 की तलाश करूंगा और आपको बताऊंगा कि यह काम करता है या नहीं। – j4x

+0

@ मार्क बी: सी ++ मानक यह इंगित नहीं करता है कि यदि आप नामस्थान में संलग्न क्लास टेम्पलेट हैं तो आपके मित्र घोषणाओं को चुपचाप अनदेखा किया जाना चाहिए। मैं निष्कर्ष निकालता हूं कि एक संकलक जो इसे त्रुटि में होना चाहिए। मैं इसे साबित नहीं कर सकता, संभवतः पूरे मानक को उद्धृत करके। –

संबंधित मुद्दे