2017-03-17 15 views
6

मैं कुशलता से एक std :: सरणी के तत्वों के साथ एक पैरामीटर पैक से तर्क गुणा करने के लिए चाहते हैं के साथ पैरामीटर पैक तर्क गुणा इस के चारों ओर मेरे दिमाग को काफी लपेटो। मैंने इंडेक्स अनुक्रम की सड़क शुरू कर दी, लेकिन मैं समझ सकता हूं कि संक्षेप में कैसे शामिल किया जाए।C++ 17 कुशलता से std :: सरणी तत्वों

मैं सी ++ 17 का उपयोग कर रहा हूं, इसलिए अगर वे कोड को सरल बनाते हैं तो गुना अभिव्यक्ति उचित गेम होती है।

किसी भी पॉइंटर्स के लिए धन्यवाद।

संपादित करें: छद्म कोड को स्पष्ट करें। एकमात्र छद्म भाग अभिव्यक्ति Is[i] है जो i'th पैरामीटर पैक तर्क को संदर्भित करता है।

टीसी के नीचे इस सवाल का जवाब सही था और यहाँ मेरा अंतिम कोड एक सदस्य समारोह है जो है:

unsigned int index(auto... indexes) 
{ 
    unsigned int idx = 0, i = 0; 
    (..., (idx += indexes * m_strides[i++])); 
    return idx; 
} 

इस लेखन के रूप में, कोड -fconcepts ध्वज के साथ जीसीसी 6.3.0 का उपयोग कर संकलित है, जो अवधारणा टीएस में लाता है।

auto... indexes का उपयोग template<typename Args> f(Args... indexes) के लिए लघुरूप है। मैंने तर्कों के लिए एक हस्ताक्षरित int अवधारणा का उपयोग करने की कोशिश की, लेकिन मैं इसे काम नहीं कर सका।

(...,) गुना प्रमुख तत्व है और की तरह कुछ करने के लिए फैलता है (यदि आप कर सकते थे वास्तव में [] पैरामीटर पैक में):

idx += indexes[0] * m_strides[i++], idx += indexes[1] * m_strides[i++], etc. 

अंतर्दृष्टि मैं याद आ रही थी था।

+0

मैं उत्सुक क्या संकलक आप उपयोग कर रहे हूँ। – ThomasMcLeod

+0

@ थॉमसएमसीएलओड जीसीसी 6.3.0 - इसमें फोल्ड एक्सप्रेशन और कुछ अन्य सी ++ 17 फीचर्स हैं। – RandomBits

+1

@ थॉमस एमसीएलओड जीसीसी 7 सी ++ 17 पूर्ण है (libstdC++ हालांकि नहीं) –

उत्तर

3

मुझे auto... काम करने के लिए नहीं मिल सकता है, इसलिए मैंने index के हस्ताक्षर को बदल दिया।

index_sequence का उपयोग करने के लिए आपको एक सहायक फ़ंक्शन (index_helper) की आवश्यकता होगी, क्योंकि यह सूचकांक भरने के लिए टेम्पलेट तर्क कटौती पर निर्भर करता है।

#include <array> 
#include <cstdio> 

template <typename... T, size_t... i> 
//      ^~~~~~~~~~~ 
//      use deduction to make {i...} = {0, 1, 2, ..., n} 
static int index_helper(const std::array<int, sizeof...(T)>& strides, 
         std::index_sequence<i...>, 
         T... Is) 
{ 
    return (0 + ... + (strides[i] * Is)); 
} 

template <typename... T> 
int index(const std::array<int, sizeof...(T)>& strides, T... Is) { 
    return index_helper(strides, std::make_index_sequence<sizeof...(T)>(), Is...); 
//        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
//        generates {0, 1, 2, ..., n} 
} 

int main() { 
    printf("%d\n", index({1, 100, 100000, 1000}, 2, 3, 5, 7)); 
    // 507302 
} 
+0

मूर्खतापूर्ण रूप से शामिल किए गए प्रकारों को 'constexpr' बनाने के लिए मूर्खतापूर्ण नहीं है। : -] – ildjarn

1

आप एक ही प्रकार है कि कॉपी करने के लिए/स्थानांतरित सस्ती है में तर्क पैक नीचे हथौड़ा कर सकते हैं, तो आप बस इसे एक सरणी में बना सकते हैं:

T arr[] = { static_cast<T>(Is)... }; // for some T, possibly common_type_t<decltype(Is)...> 

तो फिर तुम सिर्फ अपने स्यूडोकोड बदल सकते हैं असली कोड में।

अगर ऐसा संभव नहीं है, एक अल्पविराम गुना इस्तेमाल किया जा सकता:

int idx = 0, i = 0; 
(..., (idx += Is * strides[i++])); 
return idx; 
+0

मुझे एहसास नहीं हुआ कि आप इस तरह के गुना में एक इंडेक्स चर का उपयोग और संशोधित कर सकते हैं। यह उपयोगी है। – RandomBits

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