2017-06-14 48 views
9

से मूल्य प्रकारों के एक tuple को परिभाषित करने के लिए मुझे n प्रकार के tuple बनाने की आवश्यकता है। ये एन प्रकार अन्य प्रकार के मूल्य प्रकार हैं। इस स्निपेट पर विचार करें:पैरामीटर पैक

#include <boost/hana.hpp> 

namespace hana = boost::hana; 

template<class... Types> 
class CartesianProduct 
{ 
public: 
    CartesianProduct(Types... args) : sets(args...) {} 

    hana::tuple<Types...> sets; 
    hana::tuple<Types...::value_type> combination; // does not work obviously... but wo can this be done? 
}; 

इस के आवेदन इसलिए की तरह करना है: मैं इस वर्ग संभवतः विभिन्न प्रकार के कंटेनर के एक पैरामीटर पैक गुजरती हैं। कक्षा इन कंटेनरों को एक tuple sets में रखती है। कक्षा में एक क्षेत्र combination भी है जो कि कई तत्वों का एक गुच्छा है क्योंकि कंटेनरों को कक्षा में पारित किया गया था। लेकिन तत्वों के प्रकार विभिन्न कंटेनरों के मूल्य प्रकार हैं।

कक्षा तब आजीवन रूप से इसके कंटेनरों के कार्टेशियन उत्पाद का निर्माण करने और combination में वर्तमान संयोजन को स्टोर करने का इरादा रखती है। लेकिन मैं वास्तव में एक विविध फैशन में कंटेनर के मूल्य प्रकार कैसे प्राप्त कर सकता हूं?

+0

क्या सभी प्रकारों में 'value_type' है? – StoryTeller

+0

ठीक है, मैं इसे एक पूर्व शर्त बना देता हूं। –

+0

यदि आप इस आलसी कार्टेशियन उत्पाद वर्ग को लिखते हैं, तो यह शानदार होगा अगर आप इसे वापस हाना में योगदान दे सकते हैं। मैं आलसी विचार जोड़ना चाहता हूं, और अपने आप से 'कार्टेशियन_प्रॉडक्ट' को लागू करने के लिए एक अच्छा विचार हो सकता है। –

उत्तर

11

यह निश्चित रूप से किया जा सकता है। आपको बस पैक विस्तार को उचित रूप से घोषित करने की आवश्यकता है।

hane::tuple<typename Types::value_type...> combination; 

टाइपनाम विनिर्देशक के आवश्यक उपयोग पर ध्यान दें। अंगूठे का नियम पैक नाम को एक प्रकार के रूप में मानना ​​है। वही वाक्य रचनात्मक/अर्थात् बाधा लागू होती है, क्योंकि हमें यह निर्दिष्ट करना होगा कि हम स्कोप रिज़ॉल्यूशन ऑपरेटर के साथ एक प्रकार तक पहुंचते हैं। फिर अंत में पैक विस्तार का सामना करें।

Live Example

#include <vector> 
#include <map> 
#include <tuple> 

template<class... Types> 
class CartesianProduct 
{ 
public: 
    CartesianProduct(Types... args) : sets(args...) {} 

    std::tuple<Types...> sets; 
    std::tuple<typename Types::value_type...> combination; 
}; 


int main() { 
    std::vector<int> i; 
    std::map<int, std::vector<int>> m; 

    CartesianProduct<std::vector<int>, std::map<int, std::vector<int>>> 
     c(i, m); 

    return 0; 
} 
5

कथाकार सही जवाब पर विस्तार (अपने जवाब कृपया स्वीकार करते हैं):

मैं यह आसान उन्हें एक अनुवाद मेटा के मामले में लागू करने से इस तरह के प्रकार अनुवाद कल्पना करने के लिए लगता है फ़ंक्शन, उदाहरण के लिए:

#include <vector> 
#include <map> 
#include <tuple> 

namespace metafunction_impl 
{ 
    // meta function taking one type (T) and 'returning' one type. 
    // i.e. a unary metafunction 
    template<class T> struct get_value_type 
    { 
    using result = typename T::value_type; 
    }; 
} 

// provide clean interface to the metafunction 
template<class T> using GetValueType = typename metafunction_impl::get_value_type<T>::result; 

template<class... Types> 
class CartesianProduct 
{ 
public: 
    CartesianProduct(Types... args) : sets(args...) {} 

    std::tuple<Types...> sets; 

    // use my metafunction 
    std::tuple<GetValueType<Types>...> combination; 
}; 


int main() { 
    std::vector<int> i; 
    std::map<int, std::vector<int>> m; 

    CartesianProduct<std::vector<int>, std::map<int, std::vector<int>>> 
     c(i, m); 

    return 0; 
} 
+0

यह एक ठोस विज़ुअलाइज़ेशन है कि किसी को एक प्रकार के नाम के रूप में पैक की कल्पना क्यों करनी चाहिए। अंगूठे दृष्टिकोण के मेरे नियम से बेहतर है। +1 – StoryTeller

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