2012-05-31 21 views
5

के साथ सी ++ 11 मैं की तरहकॉपी एक एमपीएल :: vector_c संकलन समय पर स्थिर सरणी

#include <boost/mpl/vector_c.hpp> 
#include <boost/mpl/size.hpp> 

#include <boost/array.hpp> 

#include <iostream> 

namespace mpl = boost::mpl; 

template<std::size_t ... Args> 
struct Test 
{ 
      typedef mpl::vector_c<std::size_t, Args ...> values_type; 

      static const boost::array<std::size_t, sizeof...(Args)> values; 
}; 


int main (int argc, char** argv) 
{ 
      Test<3,2,5,6,7> test; 
      return 0; 
} 

कुछ मैं मूल्यों के साथ बढ़ावा :: सरणी सामग्री को प्रारंभ करना चाहते हैं 'निहित' है mpl :: vector_c में। यह प्रारंभिक संकलन समय पर किया जाना चाहिए। मैंने प्रीप्रोसेसर का उपयोग करके कुछ समाधानों पर देखा है, लेकिन मुझे नहीं पता कि वे विविध टेम्पलेट केस पर कैसे लागू करें।

ध्यान दें कि उपरोक्त नमूना कोड में, mpl :: vector_c के तत्व टेस्ट के टेम्पलेट पैरामीटर के समान हैं। वास्तविक कोड में यह नहीं है, इसके बजाय values_type में टेम्पलेट तर्कों की लंबाई == संख्या है, लेकिन वास्तविक मान एमपीएल एल्गोरिदम के अनुक्रम के अनुप्रयोग से परिणामस्वरूप होते हैं। इसलिए, यह न मानें कि तर्क समान हैं।

आशा है कि प्रश्न स्पष्ट है, धन्यवाद!

उत्तर

7

एक विधि पैरामीटर पैक में vector_c निकालने के लिए at_c का उपयोग करना है, और फिर इसे विस्तृत करें और सरणी को प्रारंभ करने के लिए इसका उपयोग करें।

#include <cstdio> 
#include <array> 
#include <boost/mpl/vector_c.hpp> 
#include <boost/mpl/at.hpp> 
#include <boost/mpl/size.hpp> 
#include <utils/vtmp.hpp> 
//^https://github.com/kennytm/utils/blob/master/vtmp.hpp 

template <typename MPLVectorType> 
class to_std_array 
{ 
    typedef typename MPLVectorType::value_type element_type; 
    static constexpr size_t length = boost::mpl::size<MPLVectorType>::value; 
    typedef std::array<element_type, length> array_type; 

    template <size_t... indices> 
    static constexpr array_type 
      make(const utils::vtmp::integers<indices...>&) noexcept 
    { 
     return array_type{{ 
      boost::mpl::at_c<MPLVectorType, indices>::type::value... 
     }}; 
    } 

public: 
    static constexpr array_type make() noexcept 
    { 
     return make(utils::vtmp::iota<length>{}); 
    } 
}; 

int main() 
{ 
    typedef boost::mpl::vector_c<size_t, 3, 2, 5, 6, 7> values; 

    for (size_t s : to_std_array<values>::make()) 
     printf("%zu\n", s); 
    return 0; 
} 

मैं std::array यहाँ का उपयोग कर रहा है, लेकिन आप बस boost::array करने के लिए इसे बदल सकता है और यह अभी भी काम करता है। अभिव्यक्ति

to_std_array<MPLVector>::make() 

संकलन समय में चला क्योंकि make() समारोह constexpr है।


उसी तकनीक आमतौर पर एक std::array (Convert std::tuple to std::array C++11) में एक std::tuple का विस्तार, एक समारोह कॉल ("unpacking" a tuple to call a matching function pointer) में प्रयोग किया जाता है आदि

+0

मैं के बारे में कोई लाभ के लिए 'तुलना में है या नहीं बस उत्सुक हूँ के लिए (size_t s: {3, 2, 5, 6, 7}) '? – betabandido

+0

@betabandido: नहीं, वे दोनों एक ही असेंबली (निश्चित रूप से अनुकूलन के बाद) संकलित करते हैं। – kennytm

+0

मुझे लगता है कि टेम्पलेट मेटाप्रोग्रामिंग के अधिक जटिल उपयोग में, हालांकि, प्रश्न और आपके समाधान में दिखाया गया दृष्टिकोण वास्तव में आवश्यक हो सकता है, है ना? उदाहरण के लिए, मैं उस स्थिति में सोच रहा हूं जब सरणी को एक समारोह से दूसरे में पारित करने की आवश्यकता होती है। क्या उस मामले में एक सादे सरणी ({3, 2, ...}) का उपयोग करना संभव होगा? – betabandido