2017-05-28 11 views
6
template<typename T> struct S {}; 
template<typename T> struct R {}; 

int main() { 
    typedef S<double> s1; 
    typedef S<int> s2; 
    typedef R<int> s3; 
    static_assert(xxx<s1, s2>::value, 
       "No, assertion must not be raised"); 
    static_assert(xxx<s2, s3>::value, 
       "Yes, assertion must be raised"); 
} 

तो, मैं xxx<s1, s2>::value सच वापस जाने के लिए है, जबकि xxx<s2, s3>::value संकलन समय के दौरान झूठी वापस जाने के लिए चाहते हैं।सी ++ टेम्पलेट इन्स्टेन्शियशन दौरान मूल struct/वर्ग के नाम प्राप्त

क्या सी ++ में xxx असंभव है? या, सी ++ में सैद्धांतिक रूप से संभव xxx का अस्तित्व संभव है लेकिन संभवतः किसी ने इसे अभी तक नहीं किया है?

template< 
    typename T, 
    typename V> 
struct xxx; 

template< 
template <class> class A, 
template <class> class B, 
typename X, 
typename Y> 
struct xxx<A<X>, B<Y>> { 
    static constexpr const int value = false; 
}; 


template< 
template <class> class U, 
typename X, 
typename Y> 
struct xxx<U<X>, U<Y>> { 
    static constexpr const int value = true; 
}; 

With your code on ideone

नोट::

+0

तो, 'xxx :: मूल्य' 'true' iff' t' और 'U' समान टेम्पलेट के विशेषज्ञ हैं? – Quentin

+0

@ क्वांटिन: हाँ :) –

उत्तर

5

उपयोग दो विशेषज्ञताओं है कि टेम्पलेट टेम्पलेट पैरामीटर का उपयोग इस "मिलान" प्रदर्शन करने के लिए यह एक वास्तविक प्रकार विशेषता आप value मैन्युअल रूप से सेट नहीं करना चाहिए होने के लिए, लेकिन std::integral_constant (std::true_type या std::false_type) से प्राप्त करें। मेरे फोन पर मैंने अभी एक त्वरित नकली काम किया है।

+0

* constexpr const * क्या है? –

+1

क्या आप _sure_ हैं आपको _two_ विशेषज्ञताओं की आवश्यकता है? –

+0

@HWalters No, लेकिन दो विशेषज्ञताओं के साथ यह एक त्रुटि देता है अगर यह उन प्रकारों के साथ उपयोग किया जाता है जो कुछ टेम्पलेट्स के तत्काल नहीं हैं। मैं इसे इस तरह से पसंद करूंगा, क्योंकि अब यह विशेषता केवल * एक * चीज़ (समान टेम्पलेट्स) है और दो नहीं (टेम्पलेट्स? एक ही टेम्पलेट्स?)। –

1

कुछ same_base_template की तरह:

#include <type_traits> 
template<class A, class B> 
struct same_base_template : std::false_type{}; 

template<template<class...> class S, class... U, class... V> 
struct same_base_template<S<U...>, S<V...>> : std::true_type{}; 

संपादित करें:

और एक तिहाई विशेषज्ञता के बाद से आप गैर प्रकार टेम्पलेट तर्कों का उपयोग कर रहे हैं (std::ratio):

template<class T, template<T...> class S, T... U, T... V> 
struct same_base_template<S<U...>, S<V...>> : std::true_type{}; 

Demo

यहका उपयोग करता है type_traits सेऔर false_type इसलिए हमें constexpr bool value खुद को लिखने की आवश्यकता नहीं है। मैंने यहां एक विविध टेम्पलेट का उपयोग किया क्योंकि यह थोड़ा अधिक सामान्य था और ऐसा करने के लिए केवल कुछ और कीस्ट्रोक ले गए। आपके विशिष्ट उपयोग मामले के लिए, आपको उनकी आवश्यकता नहीं है)

+0

मैं बेहतर नाम के लिए सभी कान हूं 'same_base_template'। – AndyG

+0

जब मैं शीर्षलेख 'अनुपात' सहित पहले तरीके से' same_base_template' का उपयोग करता हूं: 'int main() {typedef std :: अनुपात <7, 8> r1; typedef std :: अनुपात <12, 9> r2; static_assert (same_base_template :: मान, "नहीं, दावा नहीं उठाया जाएगा"); } ', इसे' g ++ -std = C++ 14 -o mwe mwe.cpp' के साथ संकलित करना स्थिर दावे को बढ़ाता है 'त्रुटि: स्थिर दावा विफल: नहीं, दावा नहीं उठाया जाएगा, जो मामला नहीं होना चाहिए। कोई उपाय? –

+0

@TadeusPrastowo: ऐसा इसलिए है क्योंकि 'std :: अनुपात' गैर-प्रकार के टेम्पलेट तर्क (अनुपात के लिए पूर्णांक मान) स्वीकार कर रहा है। यह मेरी अपेक्षा से थोड़ा अलग है, इसलिए मैंने एक और विशेषज्ञता जोड़ा। मैंने अपनी पोस्ट अपडेट की है। नया डेमो देखें। – AndyG

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