2012-06-19 25 views
6

जानकारी:वापसी प्रकार

मैं वर्तमान टेम्पलेट metaprogramming (निम्नलिखित this book द्वारा) जानने की कोशिश कर रहा हूँ। वे एक उपयोगी उदाहरण देते हैं जो आयामी विश्लेषण के लिए है। मैंने इसे किताब में लागू किया और सबकुछ ठीक था; see here

मेरी समस्या हालांकि, मैं मिश्रित प्रकारों के साथ आयामी विश्लेषण ढांचे का उपयोग करना चाहता हूं। इसका मतलब है कि आप वेक्टर बल देने के लिए त्वरण के आयाम वाले वेक्टर को गुणा करने वाले द्रव्यमान के आयामों के साथ एक स्केलर कह सकते थे। चूंकि यह लिंक में खड़ा है, वे सभी परिचालनों के इनपुट और आउटपुट के लिए केवल उसी प्रकार T के साथ काम करते हैं।

:

मैं तो मैं

quantity<double,mass> m(1.0); 
quantity<vect,acceleration> a(vect(0.0,0.0,-9.81)); 
quantity<vect,force> f = m*a; 

पहले प्रयास की तरह कुछ करना चाहते हैं एक 3-वेक्टर वर्ग है जिसके साथ/आदि गुणा scalars से विभाजित, के लिए सभी आवश्यक कार्य किया है है

इस बात को स्वीकार करने के लिए मैंने दो अलग-अलग प्रकारों को operator* और operator/ पर इनपुट के रूप में संभालने के लिए पुस्तक को फॉर्म बनाने का प्रयास किया, हालांकि रिटर्न प्रकार की बात होने पर मैंने दीवार पर हिट किया।

मैं यहाँ पता double * vect की वापसी प्रकार vect है लेकिन अगर वे अन्य तरीके से कर रहे हैं चारों ओर vect * double यह अभी भी एक vect है। और भी बुरा; सिद्धांत रूप में वापसी का प्रकार कुछ भी हो सकता है। इसलिए मैं की तरह

template<class T1, class T2, class Dim1, class Dim2> 
quantity<X, typename boost::mpl::transform<Dim1,Dim2,boost::mpl::plus<_1,_2> >::type> 
operator*(const quantity<T1,Dim1>& q1, const quantity<T2,Dim2>& q2) 
{ 
    return quantity<X, 
        typename boost::mpl::transform<Dim1,Dim2,boost::mpl::plus<_1,_2> >::type> 
        (q1.value()*q2.value()); 
} 

जहां Xq1.value()*q2.value() की वापसी प्रकार है और संकलन समय पर निष्कर्ष निकाला है कुछ करने के लिए operator* विस्तार करने के लिए एक तरह से करना चाहते हैं। मैंने हस्ताक्षर में एक और टेम्पलेट वर्ग T3 जोड़ने की कोशिश की और इसे T3 वापस कर दिया लेकिन ऐसा लगता है कि यह T3 को कम नहीं कर सकता है।

दूसरा प्रयास:

अगला मैं इस प्रकार

template<class T1, class T2> 
struct return_type 
{ 
    auto mult_f(const T1& a, const T2& b)->decltype(a*b){return a*b;} 
    typedef decltype(mult_f) type; 
}; 

template<class T1, class T2, class Dim1, class Dim2> 
quantity<typename return_type<T1,T2>::type, typename boost::mpl::transform<Dim1,Dim2,boost::mpl::plus<_1,_2> >::type> 
operator*(const quantity<T1,Dim1>& q1, const quantity<T2,Dim2>& q2) 
{ 
    return quantity<typename return_type<T1,T2>::type, 
        typename boost::mpl::transform<Dim1,Dim2,boost::mpl::plus<_1,_2> >::type> 
        (q1.value()*q2.value()); 
} 

हालांकि इस समझ से बाहर संकलक त्रुटियों की एक भीड़ फेंकता decltype उपयोग करने की कोशिश।

प्रश्न:

मेरा प्रश्न है, तो मैं सही ढंग से decltype उपयोग कर रहा हूँ लेकिन लापता कुछ वाक्य रचना उदा typename कहीं निर्दिष्टकर्ता? या; क्या यह इस तरह से करना संभव है और यदि नहीं, तो फ़ंक्शन के रिटर्न प्रकार की गणना करना संभव नहीं है?

धन्यवाद।

उत्तर

6

ठीक है, तो पहले प्रकार return_type<T1,T2>::type नहीं है कि तुम क्या उम्मीद हो रहे हैं, लेकिन आप किस प्रकार की उम्मीद कर रहे हैं किया जा रहा है एक विधि, के प्रकार के अर्थात् T3 साथ T3 (return_type::*)(const T1&, const T2&) है।आप एक मध्यवर्ती वर्ग का उपयोग करना चाहते हैं, तो आप उपयोग कर सकते हैं:

template <typename T1, typename T2> 
struct return_type 
{ 
    typedef decltype(std::declval<T1>()*std::declval<T2>()) type; 
}; 

लेकिन तुम भी सीधे decltype(T1()*T2()) का उपयोग उत्पाद के प्रकार प्राप्त करने के लिए कर सकता है।

संपादित करें: मैंने कोड को ildjarn के सुझाव के साथ संपादित किया है, इसलिए डिफ़ॉल्ट-रचनात्मक प्रकारों की आवश्यकता नहीं है। बस <utility>

+0

हाँ, मैं संकलक आउटपुट से बता सकता हूं कि मुझे पूरा फ़ंक्शन हस्ताक्षर मिल रहा था। मुझे नहीं पता कि मैं चीजों को इतना जटिल क्यों कर रहा था, आपका उदाहरण ठीक संकलित करता है :) डिफ़ॉल्ट कन्स्ट्रक्टर आवश्यकता यहां मेरे लिए कोई समस्या नहीं है। – Dan

+2

@ डैन: ध्यान दें कि पुस्तक सी ++ 11 और 'decltype' /' auto' उपलब्धता से पहले लिखी गई थी, जिसने चीजों को ** अधिक ** अधिक जटिल बना दिया। –

+2

'decltype (T1() * T2())' 'decltype के साथ बदलें (std :: declval () * std :: declval ()) 'और अब आपको डिफ़ॉल्ट रचनात्मकता की आवश्यकता नहीं है। – ildjarn

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