2017-07-03 7 views
5

मैं संकल्पना लाइट टीएस के बारे में जानने की कोशिश कर रहा हूं जिसे अभी तक मानक में विलय नहीं किया गया है। मैं अवधारणा निकायों में शॉर्ट-सर्किटिंग विच्छेदन के व्यवहार के बारे में उलझन में हूं।सी ++ संकल्पना लाइट: अवधारणा निकायों में शॉर्ट सर्किटिंग

यहाँ एक छोटा सा उदाहरण है:

#include <type_traits> 
#include <iostream> 

template <typename T, typename ... Ts> concept bool myconcept = 
(sizeof...(Ts) == 0) || (std::is_same_v<T, std::common_type_t<Ts...>>); 

template <typename ... Ts> 
void myfunc(Ts ... args) requires myconcept<int, Ts...> { 
    (... , (std::cout << args << std::endl)); 
} 

int main() { 
    myfunc(); 
    return 0; 
} 

जीसीसी 7.1 और -fconcepts साथ संकलन, त्रुटि देता है:

error: cannot call function 'void myfunc(Ts ...) requires myconcept<int, Ts ...> [with Ts = {}]' 

इस उदाहरण में, std::common_type_t<Ts...> मौजूद नहीं है के बाद से struct std::common_type<Ts...> नहीं है यदि कोई सदस्य type है। हालांकि, मुझे लगता है कि इस संकलन चाहिए क्योंकि concepts and constraints पर cppereference.com के दस्तावेज़ कहा गया है कि

Disjunctions are evaluated left to right and short-circuited (if the left constraint is satisfied, template argument deduction into the right constraint is not attempted).

के बाद से sizeof...(Ts) == 0 संतुष्ट है, टेम्पलेट तर्क कटौती दूसरी बाधा का प्रयास नहीं किया जाना चाहिए और आवश्यकता myconcept<int, Ts...> संतुष्ट होना चाहिए।

#include <type_traits> 
#include <iostream> 

template <typename ... Ts> 
void myfunc(Ts ... args) requires (sizeof...(Ts) == 0) || (std::is_same_v<int, std::common_type_t<Ts...>>) { 
    (... , (std::cout << args << std::endl)); 
} 

int main() { 
    myfunc(); 
    return 0; 
} 

इस व्यवहार के लिए एक अच्छा विवरण है:

अजीब, आवश्यकताओं समारोह declarator में सीधे रखकर कार्यक्रम को संकलित करने के क्या कारण हैं? धन्यवाद।

+0

मैं इस जानकारी कहां मिल सकती है "अवधारणाओं लाइट टीएस अभी तक यह है कि मानक में मर्ज करने के लिए"? मेरी आखिरी जानकारी यह स्वीकार नहीं की गई थी ... – Klaus

उत्तर

2

cppreference पर दिखाई देने वाले आम आदमी की व्याख्या सही है। n4674 draft से शब्दों का चयन के साथ-साथ काफी स्पष्ट है:

A conjunction is a constraint taking two operands. A conjunction of constraints is satisfied if and only if both operands are satisfied. The satisfaction of a conjunction’s operands are evaluated left-to-right; if the left operand is not satisfied, template arguments are not substituted into the right operand, and the constraint is not satisfied. […]

(। 17.10.1.1 तार्किक संचालन से [temp.constr.op] §2) शब्दों के सभी के बाद से है कि ठीक स्थापित हम कैसे अवधारणाओं से जाने के लिए और परमाणु बाधाओं के संयोजन या संयोजन के लिए टेम्पलेट काफी लंबा है, हम आम आदमी के स्पष्टीकरण के साथ रहेंगे।

Is there a good explanation for this behavior? Thanks.

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

template<typename T, typename... Ts> 
concept bool refactored = std::is_same_v<T, std::common_type_t<Ts...>>; 

template<typename T, typename... Ts> 
concept bool myconcept = sizeof...(Ts) == 0 || refactored<T, Ts...>; 

Coliru demo

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