2012-01-24 17 views
14

मुझे आश्चर्य है कि क्या अगर मैं एक वर्ग के कुछ सदस्य के लिए परीक्षण और सदस्य निजी है क्या प्रतिक्रिया sfinae होगा? क्या यह कड़ी मेहनत कर देगा या यह ठीक कहेंगे या क्या यह sfinae तरीके से त्रुटि होगी?क्या एसएफआईएनएई निजी पहुंच उल्लंघन का पता लगा सकता है?

+3

... क्या आपने वास्तव में इसका परीक्षण किया था? – Mehrdad

+5

नहीं मैंने इसका परीक्षण नहीं किया। मैं पूरी तरह से अनुरूप कार्यान्वयन के बारे में नहीं जानता। –

+1

@ मेहरदाद: लेकिन परीक्षण के आउटपुट की व्याख्या कैसे करें? आपको पता चलेगा कि * कंपाइलर * इसका व्याख्या कैसे करता है, लेकिन आप कैसे जानेंगे कि संकलक मानक अनुपालन है या नहीं? –

उत्तर

11

हां।

संपादित करें: सी ++ 11 स्टैंडर्ड बोली से §14.8.2 [temp.deduct]

8/ गलत प्रकार या अभिव्यक्ति में एक प्रतिस्थापन परिणाम, प्रकार कटौती में विफल रहता है । एक अमान्य प्रकार या अभिव्यक्ति वह है जो प्रतिस्थापित तर्कों का उपयोग करके लिखे जाने पर बीमार हो जाएगी। [नोट: पहुँच जाँच प्रतिस्थापन की प्रक्रिया के हिस्से के रूप में किया जाता है। अंत टिप्पणी]

यह मेरे लिए पता चलता है कि private एक SFINAE त्रुटि हो सकती है। पढ़ना:

फ़ंक्शन प्रकार और उसके टेम्पलेट पैरामीटर प्रकारों के तत्काल संदर्भ में केवल अमान्य प्रकार और अभिव्यक्तियों का परिणाम कटौती विफलता हो सकता है। [नोट: प्रतिस्थापित प्रकारों और अभिव्यक्तियों के मूल्यांकन का परिणाम क्लास टेम्पलेट विशेषज्ञता और/या फ़ंक्शन टेम्पलेट विशेषज्ञता के तत्कालता, अंतर्निहित परिभाषित कार्यों की पीढ़ी आदि के दुष्प्रभावों के परिणामस्वरूप हो सकता है। इस तरह के साइड इफेक्ट्स में नहीं हैं "तत्काल संदर्भ" और कार्यक्रम किया जा रहा है बीमार formed. अंत टिप्पणी]

"तत्काल संदर्भ" मेरे लिए इतना स्पष्ट नहीं है में परिणाम कर सकते ... लेकिन यह मेरी बात का खंडन नहीं करता है :)

EDIT

तो मुझे लगता है कि यह एक SFINAE तरह से बाहर त्रुटि जाएगा, यह आगे बजना से इस अंश से इसकी पुष्टि की है:

// clang/Basic/DiagnosticIDs.h:185-209 

    /// \brief Enumeration describing how the the emission of a diagnostic should 
    /// be treated when it occurs during C++ template argument deduction. 
    enum SFINAEResponse { 
    /// \brief The diagnostic should not be reported, but it should cause 
    /// template argument deduction to fail. 
    /// 
    /// The vast majority of errors that occur during template argument 
    /// deduction fall into this category. 
    SFINAE_SubstitutionFailure, 

    /// \brief The diagnostic should be suppressed entirely. 
    /// 
    /// Warnings generally fall into this category. 
    SFINAE_Suppress, 

    /// \brief The diagnostic should be reported. 
    /// 
    /// The diagnostic should be reported. Various fatal errors (e.g., 
    /// template instantiation depth exceeded) fall into this category. 
    SFINAE_Report, 

    /// \brief The diagnostic is an access-control diagnostic, which will be 
    /// substitution failures in some contexts and reported in others. 
    SFINAE_AccessControl 
    }; 

SFINAE के मामले में अभिगम नियंत्रण के संबंध में विशेष मामलों रहे हैं।

2

मैं ऐसा नहीं सोचता।

11/4 "सदस्य अभिगम नियंत्रण" (सी ++ 03):

किसी दिए गए निर्माण की व्याख्या नियंत्रण का उपयोग करने के संबंध में बिना स्थापित है। यदि स्थापित की गई व्याख्या पहुंच योग्य सदस्य नाम या आधार वर्गों का उपयोग करती है, तो निर्माण खराब गठित है।

तो ओवरलोड रिज़ॉल्यूशन पहले होता है, फिर एक्सेस नियंत्रण लागू होता है।

+0

एचएम मैंने सोचा था कि अगर टेम्पलेट निर्माण खराब हो जाएगा तो sfinae होता है? –

+2

दरअसल, ऐसा लगता है कि प्रतिस्थापन के लिए ** [temp.deduct] ** में एक विशेष प्रावधान है। मेरे उत्तर में §14.8.2/8 देखें। –

5

नहीं। मैं सड़क पर हूं और मेरे पास बोली लगाने के लिए मानक नहीं है, लेकिन सिफिना संकलन के चरण में जगह लेती है जहां संकलक जांचता है कि नाम बिल्कुल मौजूद है, और बाद के चरण में पहुंच नियंत्रण जगह लेता है।

यह ओवरलोड रिज़ॉल्यूशन के समान है, जहां सभी नामों पर विचार किया जाता है, और एक मैच जो निजी है, बेहतर है, लेकिन संकलित नहीं होगा, हालांकि एक और मैच है जो "ठीक" होगा लेकिन निजी नहीं होगा।

अलावा:

कोर मुद्दा 1170 का कहना है:

1170 पहुँच टेम्पलेट तर्क कटौती के दौरान जाँच
धारा: 14.8.2 [temp.deduct]
स्थिति: एफ डी आई सबमिट करने: Adamczyk दिनांक: 2010-08-03

[मार्च, 2011 की बैठक में WP में मतदान किया।]

14.8.2 के लिए [temp.deduct] पैरा 8 अनुसार

,

पहुँच जाँच प्रतिस्थापन की प्रक्रिया के हिस्से के रूप में नहीं किया जाता है। नतीजतन, जब कटौती सफल होती है, तब भी एक त्रुटि त्रुटि परिणाम तब हो सकती है जब फ़ंक्शन तत्काल हो।

यह ओवरलोड रिज़ॉल्यूशन में एक्सेस चेकिंग के तरीके की नकल करता है। हालांकि, अनुभव दिखा दिया है कि कटौती की विफलता से पहुँच त्रुटियों की इस छूट काफी मानक पुस्तकालय पेचीदा हो, इसलिए यह नियम बदला जाना चाहिए।

प्रस्तावित संकल्प (जनवरी 2011):

14.8.2 बदलें [temp.deduct] पैरा 8 इस प्रकार है: गलत प्रकार या अभिव्यक्ति में एक प्रतिस्थापन परिणाम, प्रकार कटौती विफल रहता है

हैं । एक अमान्य प्रकार या अभिव्यक्ति वह है जो प्रतिस्थापित तर्कों का उपयोग करके लिखे गए बीमार गठित होगा। [नोट: प्रतिस्थापन प्रक्रिया के हिस्से के रूप में जांच नहीं की जाती है।अंत टिप्पणी] नतीजतन, जब कटौती सफल होता है, एक पहुँच त्रुटि अभी भी परिणाम समारोह instantiated है जब सकता है। केवल अवैध प्रकार ...

तो मेरी व्याख्या यह है कि इस सी ++ 03 में असंभव है, लेकिन सी ++ 11 संभव बना दिया है।

1

यहाँ == एक उदाहरण है कि is_comparable लागू करता है और एक संभावित रूप से निजी ऑपरेटर संभालती है। जी ++ - इस पर 4.7 chokes, लेकिन जी ++ - 4.8 और बजना ++ 3.4 सी ++ 11 मोड में सही ढंग से संभाल।

#include <iostream> 
#include <utility> 
// is_comparable trait 
template<class T> 
class is_comparable { 
    template<typename U> static char (&check (int))[1 + sizeof (decltype (
    std::declval<U>() == std::declval<U>() // trait check 
))]; 
    template<typename> static char (&check (...))[1]; 
public: 
    static constexpr const bool value = sizeof (check<T> (0)) != 1; 
}; 
// tests 
class Diff1 {};   // non-comparable 
class Diff2 {   // non-comprable, since member is private 
    bool operator== (const Diff2&); 
}; 
struct EqM { bool operator== (EqM); }; // comparable 
struct EqG {};       // comparable 
bool operator== (const EqG&, const EqG&); 
int 
main() 
{ 
    std::cout << "is_comparable:"; 
    std::cout << " void=" << is_comparable<void>::value; 
    std::cout << " Diff1=" << is_comparable<Diff1>::value; 
    std::cout << " Diff2=" << is_comparable<Diff2>::value; 
    std::cout << " int=" << is_comparable<int>::value; 
    std::cout << " EqM=" << is_comparable<EqM>::value; 
    std::cout << " EqG=" << is_comparable<EqG>::value; 
    std::cout << "\n"; 
    return 0; 
} 
// $ clang++ is_comparable.cc -std=c++11 && ./a.out 
// is_comparable: void=0 Diff1=0 Diff2=0 int=1 EqM=1 EqG=1 

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

  • कोई संबंधित समस्या नहीं^_^