2015-12-15 11 views
11

मैं एसवीएन से जीसीसी में अवधारणाओं के लाइट के साथ प्रयोग कर रहा हूं। मैंने एक ऐसी समस्या पर मारा है जो मुझे संदेह की कमी के कारण है, और अगर कोई मुझे सही दिशा में इंगित कर सकता है तो मैं इसकी सराहना करता हूं। मेरे कोड है:अवधारणाओं और घोषणा आदेश

#include <iostream> 
#include <string> 

// Uncomment this declaration to change behaviour 
//void draw(const std::string&); 

template <typename T> 
concept bool Drawable() { 
    return requires (const T& t) { 
     { draw(t) } 
    }; 
} 

void draw(const std::string& s) 
{ 
    std::cout << s << "\n"; 
} 

int main() 
{ 
    static_assert(Drawable<std::string>()); // Fails 
} 

यहाँ मैं एक सरल अवधारणा है, Drawable है, जो आवश्यक है कि एक प्रकार const T& की एक पैरामीटर, समारोह draw(t) compiles दिया इरादा है परिभाषित करते हैं।

मैं फिर एक फ़ंक्शन draw(const std::string&) परिभाषित करता हूं जो स्ट्रिंग को cout पर "खींचता है"। अंत में, मैं जांचता हूं कि std::stringDrawable अवधारणा से मेल खाता है - जिसे मैं उम्मीद करता था, क्योंकि उपयुक्त draw() फ़ंक्शन उस दायरे में है जब static_assert कहा जाता है।

हालांकि, स्थैतिक जोर विफल रहता है, जब तक कि draw(const std::string&)की अवधारणा अवधारणा परिभाषा से पहले, और मुझे नहीं पता कि क्यों।

क्या यह अवधारणाओं के साथ अपेक्षित व्यवहार है, या क्या मैं कुछ गलत कर रहा हूं?

+8

सैकड़ों डुप्लिकों के साथ बोग-मानक एडीएल समस्या। एडीएल वैश्विक नामस्थान का निरीक्षण नहीं करेगा क्योंकि इसमें शामिल किसी भी प्रकार के सदस्य नहीं हैं। टेम्पलेट के ऊपर की घोषणा को अपूर्ण करने से अस्थायी-नाम-लुकअप को टेम्पलेट परिभाषा संदर्भ में ढूंढने में सक्षम बनाता है। – Columbo

+0

तो अगर वह नेमस्पेस std में उस शून्य ड्रा घोषणा को डालता है। यह काम करना चाहिए। – West

+0

मुझे उद्घाटन वाक्य में एसवीएन संदर्भ गुम है। क्या यह किसी भी तरह से महत्वपूर्ण है? –

उत्तर

-1

चूंकि, ऊपर दिए गए कार्यों को घोषित करने की आवश्यकता है ताकि इसका उपयोग करने वाले सभी कार्यों को इसके बारे में जानना आवश्यक हो।

कक्षा में, फ़ंक्शन हेडर फ़ाइल में घोषित किए जाते हैं। यदि वे सदस्य नहीं हैं, तो उन्हें उपयोग किए जाने से पहले घोषित करने की आवश्यकता है। ऐसा इसलिए है क्योंकि संकलक शीर्ष से नीचे तक पढ़ता है और जब यह घोषणा को देखता है तो केवल एक फ़ंक्शन के बारे में जानता है।

यदि आप अवधारणा कोड और ड्रा कोड को स्वैप करते हैं तो इसे भी काम करना चाहिए।

1

समस्या एडीएल के साथ कुछ लेना देना नहीं है) लेकिन पूरी तरह से नाम लुकअप के साथ। जीसीसी द्वारा उपयोग की जाने वाली अवधारणा ड्राफ्ट n4377 है, लेकिन सी ++ मानक मसौदा मैं उपयोग कर रहा हूं n4140 है। सबसे पहले, मानक में डाइविंग से पहले हम आपकी समस्या को एक ऐसे एमसीवीई में बदल सकते हैं जिसे हम जानते हैं काम करने के लिए माना जाता है। उदाहरण:

template<typename T> concept bool C = 
    requires (T a, T b) { 
    a + b; 
    }; 

यह एक सरल आवश्यकता, [expr.prim.req.simple], कि अभिव्यक्ति की वैधता की जांच करता है। फॉर्म से मिलान करने के लिए हमारे उदाहरण को दोबारा लिखना:

template<typename T> concept bool Drawable = 
    requires (const T& x) { 
    draw(x); 
    }; 

हम देख सकते हैं कि हमारा वाक्यविन्यास ठीक है। ठीक है, एन 4377 क्या कहता है?

[expr.prim.req]/1 ए की आवश्यकता है अभिव्यक्ति टेम्पलेट तर्क पर एक्सप्रेस आवश्यकताओं के लिए एक संक्षिप्त तरीके से प्रदान करता है। एक आवश्यकता यह है कि नाम लुकअप (3.4) द्वारा चेक किया जा सकता है या और अभिव्यक्तियों के प्रकारों की जांच करके देखा जा सकता है।

[expr.prim.req]/6 आवश्यकता-शरीर आवश्यकताओं के अनुक्रम में शामिल है। ये आवश्यकताएं स्थानीय पैरामीटर, टेम्पलेट पैरामीटर, और संदर्भ संदर्भ से दिखाई देने वाली किसी भी अन्य घोषणाओं को संदर्भित कर सकती हैं। ...

समझ में आता है। हम जानते हैं कि संदर्भ वैश्विक नामस्थान है, तो n4140 क्या कहता है?

[basic.lookup.unqual]/1 3.4.1 में सूचीबद्ध सभी मामलों में, स्कोप संबंधित श्रेणियों में से प्रत्येक में सूचीबद्ध क्रम में एक घोषणा के लिए खोज कर रहे हैं; नाम के रूप में नाम के रूप में नाम लुकअप समाप्त होता है नाम के लिए मिलता है। यदि कोई घोषणा नहीं मिली है, तो कार्यक्रम खराब गठित है।

समारोह के declarator-आईडी नाम स्थान N (जहां, केवल प्रदर्शनी के उद्देश्य के लिए, N वैश्विक क्षेत्र का प्रतिनिधित्व कर सकते हैं) का एक सदस्य है जो निम्न एक समारोह की परिभाषा में उपयोग किया जाने वाला नाम होगा घोषित इससे पहले कि ब्लॉक में इसके उपयोग, जिसमें इसका इस्तेमाल किया या है इसका आवरण ब्लॉक (6.3) या में से एक में, नाम स्थान N में इसके उपयोग से पहले घोषित किया जाएगा ...

कार्य करने के लिए अवधारणा appertains के रूप में , उपरोक्त अनुच्छेद लागू होता है।

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