2016-04-07 8 views
8

साथ इस कोड (कोई निदान के साथ) बजना3.7.1 साथ संकलित लेकिन जीसीसी5.3.0 (live example) के साथ विफल:खाका जीसीसी के साथ दोस्ती त्रुटि संकलन लेकिन नहीं बजना

#include <iostream> 

template<typename T> 
struct A { 
    void foo() 
    { 
     static_cast<T*>(this)->implementation(); 
    } 
}; 

struct Crtp : A<Crtp> { 
    template<typename T> 
    friend struct A; 
private: 
    void implementation() { std::cout << "implementation()\n"; } 
}; 

int main() 
{ 
    Crtp c; 
    c.foo(); 
} 

main.cpp:13:16: error: specialization of 'A' after instantiation friend struct A;

कौन सा सही है और क्यों:

जीसीसी के त्रुटि संदेश निम्न है? क्या यह जीसीसी/क्लैंग का एक बग है?

उत्तर

4

एक पुराना जी ++ बग (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52625) लगता है।

की सूचना दी है और कभी नहीं, सही अगर मैं सही ढंग से समझ,

+1

आप सही हैं। इसके अलावा, जीसीसी में कई [मित्र मुद्दे] हैं (https://gcc.gnu.org/bugzilla/showdependencytree.cgi?id=65608&hide_resolved=1)। – akakatak

3

मुझे लगता है कि यह जीसीसी की बग है।

एक टेम्पलेट मित्र वर्ग घोषणा केवल एक घोषणा है, परिभाषा नहीं। क्लास टेम्पलेट का पुनर्वितरण तब तक स्वीकार्य है जब तक कि कक्षा-कुंजी (N4527 14.5.1.4 देखें)।

विशेषज्ञता या तत्कालता दो या दो से अधिक हो सकती है। स्पष्ट विशेषज्ञता केवल एक बार हो सकती है (N4527 14.7.3.6)।

फिर, जीसीसी के निदान अजीब है क्योंकि कोई स्पष्ट विशेषज्ञता नहीं है।

0

हम कुछ टेम्पलेट का नाम संकल्प बाधाओं है:

struct Crtp : A<Crtp> { 
    A x; // A refers to A<Crtp> 
}; 

अब बातें स्पष्ट हैं:

template<typename T> friend struct A; 

को दर्शाता है:

template<typename T> friend struct A<Crtp>; 

जो है ... हाँ, आंशिक विशेषज्ञता (वास्तव में मुश्किल एक)।

तो जीसीसी यहां सही है।

क्या आप वास्तव में क्या जरूरत है:

struct Crtp : A<Crtp> { 
friend struct A; 
private: 
    void implementation() { std::cout << "implementation()\n"; } 
}; 
संबंधित मुद्दे