2016-10-30 6 views
9

संकल्पना टीएस द्वारा प्रस्तावित एक अवधारणा के अंदर एक प्रकार के उपनाम घोषित करने के लिए typedef या using का उपयोग करना संभव है? अवधारणाओं टीएस के अनुसारसी ++ अवधारणाओं का प्रकाश और प्रकार उपनाम घोषणा

main.cpp: In function ‘concept bool TestConcept()’: 
main.cpp:8:9: error: expected primary-expression before ‘using’ 
     using V = T; 
     ^~~~~ 
main.cpp:8:9: error: expected ‘}’ before ‘using’ 
main.cpp:8:9: error: expected ‘;’ before ‘using’ 
main.cpp:4:14: error: definition of concept ‘concept bool TestConcept()’ has multiple statements 
concept bool TestConcept() 
       ^~~~~~~~~~~ 
main.cpp: At global scope: 
main.cpp:11:1: error: expected declaration before ‘}’ token 
} 
^ 
+0

ऐसा लगता है कि आप 'typedef V T;' का उपयोग करना चाहते हैं, जो 'T' से' V' होगा। 'उपयोग' नामस्थानों, या नामस्थान से विशिष्ट पहचानकर्ताओं का आह्वान करने के लिए है। यहां एक उदाहरण दिया गया है: http://stackoverflow.com/questions/10103453/is-typedef-inside-of-a-function-body-a-bad-programming-practice –

+1

@JamesMurphy क्षमा करें, लेकिन सी ++ 11 के बाद से आप कर सकते हैं 'टाइपिंग' के साथ पहले किए गए टाइप उपनामों को व्यक्त करने के लिए 'उपयोग' कीवर्ड का उपयोग करें। यहां संदर्भ है: http://en.cppreference.com/w/cpp/language/type_alias। – erikzenker

+0

@JamesMurphy उदाहरण भी टाइपेडफ के साथ विफल रहता है, मूल रूप से एक ही त्रुटि संदेश के साथ। जैसे erikzenker ने कहा, वाक्यविन्यास आजकल समकक्ष होना चाहिए। – Slizzered

उत्तर

2

संख्या: अगर मैं निम्नलिखित मेगावाट की तरह कुछ कोशिश, कोड (जीसीसी 6.2.1 और -fconcepts स्विच के साथ)

#include <type_traits> 

template<typename T> 
concept bool TestConcept() 
{ 
    return requires(T t) 
    { 
     using V = T; 
     std::is_integral<V>::value; 
    }; 
} 

int main() 
{ 
    return 0; 
} 

संकलन नहीं है परिणामस्वरूप त्रुटि , एक आवश्यकता है:

requirement:
    simple-requirement
    type-requirement
    compound-requirement
    nested-requirement

जहां एक सरल-आवश्यकता एक एक्सप्रेस है आयन; और टाइप-आवश्यकताtypename T::inner जैसा कुछ है। अन्य दो ध्वनि जैसे नाम बताता है।

एक प्रकार उपनाम एक घोषणा है, अभिव्यक्ति नहीं, और इसलिए आवश्यकता की आवश्यकता को पूरा नहीं करता है।

+0

यह मेरे लिए अनावश्यक रूप से प्रतिबंधित लगता है। क्या आपको पता है कि एक ही जटिल प्रकार को बार-बार लिखने के बजाय उचित कार्यवाही मौजूद है या नहीं? – Slizzered

2

This feels unnecessarily restrictive to me. Do you know if there exists a reasonable workaround instead of writing the same complicated type over and over again?

आप किसी अन्य अवधारणा के लिए बाधाओं के कार्यान्वयन को स्थगित कर सकते हैं टेम्पलेट पैरामीटर के रूप में प्रकार गुजर:

template<typename Cont, typename It, typename Value> 
concept bool InsertableWith = requires(Cont cont, It it, Value value) { 
    // use It and Value as much as necessary 
    cont.insert(it, std::move(value)); 
}; 

template<typename Cont> 
concept bool Insertable = requires { 
    // optional 
    typename Cont::const_iterator; 
    typename Cont::value_type; 
} && InsertableWith<Cont, typename Cont::const_iterator, typename Cont::value_type>; 

आपको लगता है कि कर विचार कर रहे हैं, मैं तुम्हें करने से पहले सरल उदाहरण पर यह कोशिश का सुझाव एक निर्णय। आप अपनी अवधारणाओं और बाधाओं को कैसे लिखते हैं यह निर्धारित करता है कि एक कंपाइलर त्रुटियों की रिपोर्ट कैसे करेगा, और निश्चित रूप से अच्छी त्रुटियां होने से अवधारणाओं को उपयोगी बनाने का एक बड़ा हिस्सा है। त्रुटियों को समझने में कठोर परिश्रम करते समय अपनी अवधारणाओं को लिखना आसान बनाना एक व्यापार-बंद नहीं है, मैं हल्के से ले जाऊंगा।

उदाहरण के लिए, इसलिए मैंने अनावश्यक रूप से typename Cont::const_iterator; को एक स्पष्ट बाधा के रूप में जोड़ा। यह संकलक को इस प्रकार की आवश्यकता की रिपोर्ट करने का मौका देता है। मैं अवधारणा के नाम के रूप में InsertableWith चुनने में भी सावधान था: मैं आसानी से detail::Insertable के साथ आसानी से चला सकता था, लेकिन Insertable और detail::Insertable दोनों त्रुटियों के परिणामस्वरूप अधिक भ्रमित हो सकता था।

अंत में ध्यान दें कि यह सभी संकलक के कार्यान्वयन की गुणवत्ता पर निर्भर करता है, इसलिए मुझे उम्मीद है कि समय के लिए कोई दृष्टिकोण निश्चित नहीं होगा। मैं इस Coliru demo के साथ खेलना प्रोत्साहित करता हूं।

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