2014-11-22 5 views
5

में कॉपी सरणी मैंने constexpr कॉपी कन्स्ट्रक्टर के साथ एक कक्षा लिखी। (यह उदाहरण को सरल बनाने के लिए एक संरचना है।) फ़ील्ड में से एक एक सरणी है। मैं इसे भी कॉपी करना चाहता हूं।constexpr कन्स्ट्रक्टर

struct Foo 
{ 
    static constexpr int SIZE = 4; 
    constexpr Foo() = default; 
    constexpr Foo(const Foo &foo) : 
      arr{foo.arr[0], foo.arr[1], foo.arr[2], foo.arr[3]}, 
      bar(foo.bar+1) {} 
    int arr[SIZE] = {0, 0, 0, 0}; 
    int bar = 0; 
}; 

मेरा संस्करण काम करता है लेकिन यह स्केलेबल नहीं है। अगर मैं SIZE बदलता हूं, तो मुझे कन्स्ट्रक्टर को संशोधित करना होगा। इसके अलावा, कोड बदसूरत लग रहा है।

क्या यह कन्स्ट्रक्टर में सरणी की प्रतिलिपि बनाने का कोई बेहतर तरीका है? निर्माता constexpr होना चाहिए।

+7

Doesn डिफ़ॉल्ट प्रतिलिपि निर्माता नौकरी नहीं करते हैं? – juanchopanza

+0

constexpr गारंटी नहीं है कि सरणी को उत्परिवर्तित नहीं किया जाएगा? मूल्य से प्रतिलिपि क्यों परेशान करें और न केवल एक सूचक? – tohava

+0

@juanchopanza मैं ईमानदारी से अपने दिमाग को पार नहीं किया। लेकिन सवाल सवाल है। आप मान सकते हैं कि कक्षा में कुछ फ़ील्ड हैं जिन्हें प्रतिलिपि बनाने के लिए कुछ गणना की आवश्यकता है। इसके अलावा यह भविष्य में होगा। –

उत्तर

3

आप std :: array का उपयोग कर सकते हैं। चूंकि यह एक समग्र प्रकार है, मेरा मानना ​​है कि यह काम करेगा।

+0

यह एक अच्छा जवाब है, लेकिन मैं जानना चाहता हूं कि आप इसे सीधे कैसे कर सकते हैं। –

3

सी ++ 14 में आप सिर्फ सरणी कॉपी करने के लिए एक पाश का उपयोग कर सकते हैं:

constexpr Foo(const Foo &foo) 
    : bar(foo.bar + 1) 
{ 
    for (int i = 0; i < SIZE; ++i) 
     arr[i] = foo.arr[i]; 
} 

मतलब यह नहीं है कि आप यह करना चाहिए। मैं इसके बजाय std::array का उपयोग करने की अनुशंसा करता हूं। उदाहरण के लिए, यदि arr गैर-तुच्छ प्रारंभिकता वाले कुछ वर्ग प्रकार की एक सरणी है, तो यह std::array और डिफ़ॉल्ट प्रतिलिपि कन्स्ट्रक्टर का उपयोग करते समय प्रति-प्रारंभिकता के बजाय डिफ़ॉल्ट रूप से प्रारंभिक और फिर प्रतिलिपि बनाई जाएगी।

+0

यह सी ++ 11 है, क्षमा करें। –

+3

यह सी ++ 14 में भी एक अच्छा सामान्य दृष्टिकोण नहीं है हालांकि: यह प्रत्येक सरणी तत्व को प्रतिलिपि बनाने के बजाय प्रत्येक सरणी तत्व को असाइन करता है। इससे कोई फर्क नहीं पड़ता कि यह 'int' की सरणी है, लेकिन यह अन्य प्रकारों के लिए महत्वपूर्ण है। – hvd

1

आप की तरह कुछ कर सकते हैं सी ++ 11 बस सरणी

template <int LENGTH> 
constexpr bool copy_array(const char (&from)[LENGTH + 1], char (&to)[LENGTH], int index) 
{ 
    return index < LENGTH ? (to[index] = from[index], copy_array(from, to, ++index)) : false; 
} 

constexpr char src[] = "ab"; 
char dest[2]; 
copy_array(src, dest, 0); 

संपादित कॉपी करने के लिए: और अपने संदर्भ में, आप की तरह कुछ करने के लिए सक्षम हो सकता है:

#include <iostream> 
#include <type_traits> 
#include <array> 
#include <utility> 

struct Foo 
{ 
    static constexpr int SIZE = 4; 
    constexpr Foo() = default; 
    constexpr Foo(const Foo &foo) : 
      arr{foo.arr}, 
      bar(foo.bar + 1) {} 
    std::array<int, SIZE> arr = {{0, 0, 0, 0}}; 
    int bar = 0; 
}; 

int main() 
{ 
    constexpr Foo foo1; 
    constexpr Foo foo2(foo1); 

    std::cout << foo1.bar << std::endl; 
    std::cout << foo2.bar << std::endl; 

    return 0; 
} 
+0

क्या आप अपने उदाहरण में एक संपूर्ण कन्स्ट्रक्टर परिभाषा शामिल कर सकते हैं? –

+0

मैंने एक कॉन्स्टेक्स वर्ग कन्स्ट्रक्टर के संदर्भ में कोशिश की लेकिन यह आसान नहीं है। और एक और तरीका है: टेम्पलेट स्ट्रक्चर फू {टेम्पलेट <टाइपनाम ... Args> constexpr Foo (Args && ... args): डेटा {args} {} char डेटा [LENGTH];}; – xiaodong

+0

मैं नहीं देख सकता कि यह मेरी समस्या का समाधान कैसे करेगा। –

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