2014-07-09 19 views
9

में फिक्स्ड लम्बाई वैराडिक पैरामीटर पैक मैं सी ++ 11 का उपयोग कर एक सामान्यीकृत एन-आयामी वेक्टर क्लास को कार्यान्वित करने का प्रयास कर रहा हूं। आदर्श रूप में, मैं वेक्टर के "टी" और आयामों की संख्या "एन" प्रदान करना चाहता हूं और कन्स्ट्रक्टर उचित तर्कों को स्वीकार करता हूं।सी ++ 11

दुर्भाग्यवश, मैं एक पैरामीटर पैक की टेम्पलेट निर्दिष्ट निर्दिष्ट लंबाई की अनुमति देने का कोई तरीका नहीं ढूंढ पाया।

क्या मैं के लिए देख रहा हूँ की तरह

template<typename T, size_t n> 
class Vector { 
public: 
    Vector(T... values /* values is exactly n parameters long */); 

    ... 
}; 

कुछ ऐसा करना संभव है है?

+3

इसके लिए 'std :: array' है। – 101010

उत्तर

13

ठीक है, आप std :: enable_if उपयोग कर सकते हैं:

template <typename... Args, 
    typename = typename std::enable_if< 
     sizeof...(Args) == n 
    >::type> 
explicit Vector(Args&&... values) : _data{ std::forward<Args>(values)... } {} 

यह कंस्ट्रक्टर्स कि एन के अलावा अन्य args के आकार को स्वीकार कर सकते शैडो होगा।

+0

दिलचस्प। क्या आप कन्स्ट्रक्टर प्रारंभिक सूची में क्या हो रहा है समझा सकते हैं? मैं सी ++ 11 मानक के लिए बिल्कुल नया हूं और यह समझने में कठिन समय है कि यह कैसे काम करता है। धन्यवाद! –

+1

यह सिर्फ सरल चालक कन्स्ट्रक्टर है। मुझे लगता है कि __data इस तरह परिभाषित किया गया है: टी __data [n]; प्रारंभकर्ता सूची केवल कन्स्ट्रक्टर तर्कों से __data सरणी में मानों को ले जाती है। आपको std :: move के बारे में पढ़ना चाहिए, यह बहुत बढ़िया है। – Garrappachc

+3

नोट करें कि एक या दो अंडरस्कोर उपसर्ग अक्सर कंपाइलर्स द्वारा उपयोग किया जाता है ... – jiggunjer

3

आप भी इस चाल इस्तेमाल कर सकते हैं:

template <typename T, std::size_t n, typename = std::make_index_sequence<n>> 
class Vector; 

template <typename T, std::size_t n, std::size_t... Ignore> 
class Vector<T, n, std::index_sequence<Ignore...>> 
{ 
    template <size_t > using ith_T = T; 
public: 
    Vector(ith_T<Ignore>... values) 
    { 
    } 
}; 

यह सुनिश्चित होगा कि Vector प्रकार T, आवश्यक कोई अतिरिक्त templating की n तर्क लेता है। आप नामस्थान में Ignore... कुरूपता को अतिरिक्त रूप से छुपा सकते हैं:

namespace details { 
    template <typename T, std::size_t n, typename = std::make_index_sequence<n>> 
    class Vector; 

    ... 
} 

template <typename T, std::size_t n> 
using Vector = details::Vector<T, n>; 
+0

क्या आप कृपया कुछ ऐसा बता सकते हैं जो यहां होता है? – Kikohs

+0

@Kikohs एक पैक सही लंबाई (डिफ़ॉल्ट तर्क के माध्यम से और 'make_index_sequence') के द्वारा बनाया गया है। यह पैक विशेषज्ञता द्वारा मिलान पैटर्न है। इस पैक को तब इस तरह से अनपॅक किया जाता है कि प्रत्येक उदाहरण प्रकार 'टी' बन जाता है। हमें एक सीटीओ मिलता है जो 'टी' के बिल्कुल 'एन' उदाहरण मांगता है। मुझे बैरी के 'विवरण :: मेक' का उपयोग पसंद नहीं है (क्यों 'decltype' का उपयोग करें?' टेम्पलेट ith_T = टी; वेक्टर (ith_T ...) ') का उपयोग करके, और यदि अंतिम उपयोगकर्ता एक दोषपूर्ण तीसरी तर्क चीजें पास करता है जो मसालेदार हो जाता है, लेकिन इसके अलावा, यह काम करता है। – Yakk

+0

@Yakk यह नाटकीय रूप से बेहतर है, हां। – Barry