2017-02-28 20 views
10

निम्नलिखित कोड पर विचार करें: आप test2 लाइन uncomment और जी ++ के साथ कोड को संकलित करने का प्रयास करेंएक फ़ंक्शन पॉइंटर को टेम्पलेट फ़ंक्शन में स्पष्ट और फ़ंक्शन नाम के बिना क्यों नहीं तुलना कर सकता है?

void func(int) {} 
template<typename T> void templatedFunc(T) {} 
int main() 
{ 
    void (*p)(int) = func; 

    bool test1 = p==func; 
    //bool test2 = p==templatedFunc<int>; // compilation error 
    bool test3 = p==&templatedFunc<int>; // but this works 
} 

, आपको निम्न त्रुटि मिल जाएगा:

test.cpp: In function ‘int main()’: 
test.cpp:8:21: error: assuming cast to type ‘void (*)(int)’ from overloaded function [-fpermissive] 
    bool test2 = p==templatedFunc<int>; // compilation error 
        ^~~~~~~~~~~~~~~~~~ 

मैं जी में इस परिणाम को प्राप्त ++ 5.3.0 और 6.2.0। साथ ही, क्लैंग ++ 3.6.0 के साथ संकलन चेतावनी के बिना सफल होता है।

कौन सा कंपाइलर मानक के अनुसार सही है - g ++, जो त्रुटि या clang ++ देता है, जो नहीं करता है?

और यदि जी ++ सही है, तो ऑपरेटर के स्पष्ट पते की आवश्यकता के संबंध में सामान्य कार्यों बनाम टेम्पलेट किए गए कार्यों के साथ ऐसी असममितता क्यों है?

+0

मेरा सामान्य ज्ञान मुझे बताता है कि इस स्थिति में क्लैंग सही है, क्योंकि पूरी तरह से विशिष्ट फ़ंक्शन टेम्पलेट (या बल्कि एक तात्कालिकता) को सामान्य कार्य माना जाता है और इस तरह कार्य करना चाहिए। – DeiDei

+0

क्या यह आपको 'शून्य (* पी) (int) = templatedFunc करने की अनुमति देता है;', या इसके लिए '&' की आवश्यकता होती है? – TripeHound

+0

बीटीडब्ल्यू, बेवकूफ तरीका '&' का उपयोग करना है। – Jarod42

उत्तर

1

यह एक जीसीसी बग है, और आप सी ++ मानक में एक कोने मामले में कर रहे हैं, अतिभारित समारोह के पता §13.4 ([over.over]/1):

A use of an overloaded function name without arguments is resolved in certain contexts to a function, a pointer to function or a pointer to member function for a specific function from the overload set. A function template name is considered to name a set of overloaded functions in such contexts. The function selected is the one whose type is identical to the function type of the target type required in the context. [ Note: That is, the class of which the function is a member is ignored when matching a pointer-to-member-function type. — end note ] The target can be:

(1.1) — an object or reference being initialized (8.5, 8.5.3, 8.5.4),

(1.2) — the left side of an assignment (5.18),

(1.3) — a parameter of a function (5.2.2),

(1.4) — a parameter of a user-defined operator (13.5),

(1.5) — the return value of a function, operator function, or conversion (6.6.3),

(1.6) — an explicit type conversion (5.2.3, 5.2.9, 5.4), or

(1.7) — a non-type template-parameter (14.3.2).

The overloaded function name can be preceded by the & operator. An overloaded function name shall not be used without arguments in contexts other than those listed. [ Note: Any redundant set of parentheses surrounding the overloaded function name is ignored (5.1). — end note ]

आप क्या देखें (सूची) (1.7) से सूची में कमी क्या है ... अंतर्निहित ऑपरेटर!

आप operator == की एक अधिभार की घोषणा तो दोनों जीसीसी तुलना के साथ शिकायत नहीं होगी, की तुलना में आप स्पष्ट रूप से टेम्पलेट समारोह विशेषज्ञ की जरूरत नहीं है कि और अधिक:

void func(int) {} 
template<class T> 
void templatedFunc(T) {} 
struct s{}; 
bool operator==(s, void(*)(int)){return false;} 
int main() 
{ 
    void (*p)(int) = templatedFunc; 

    bool test1 = p==func; 
    bool test2 = s{} == templatedFunc<int>; // no error - no overload resolution 
    bool test3 = s{} == templatedFunc; // no error - overload resolution 
    bool test4 = p == templatedFunc<int>; // gcc error, but not an error - 
             // no overload resolution 
//bool test5 = p == templatedFunc; // error - overload resolution not 
           // performed for built-int operators 

} 

test2 और test3 जीसीसी के साथ संकलित करता है। test4 जीसीसी पर संकलित नहीं है, लेकिन कोई ओवरलोड रिज़ॉल्यूशन नहीं है, आप स्पष्ट रूप से फ़ंक्शन को विशेष रूप से विशिष्ट करते हैं। यह वास्तव में संकलन करना चाहिए। test5 मानक में बताए अनुसार संकलित नहीं करता है। इस मामले में जीसीसी test4 के लिए एक ही त्रुटि संदेश उत्पन्न करता है। यह निश्चित रूप से एक जीसीसी बग है।

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

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