2016-06-29 31 views
8

मैं थोड़ा कैसे व्यवहार में सी ++ निरंतर एक्सप्रेशन का उपयोग करने के बारे में अधिक जानने की कोशिश कर रहा हूँ और समझाने के उद्देश्य से निम्नलिखित मैट्रिक्स वर्ग खाका बनाया:संकलक इस बारे में शिकायत क्यों करता है कि यह एक कॉन्स्टेक्स नहीं है?

#include <array> 

template <typename T, int numrows, int numcols> 
class Matrix{ 
public: 
    using value_type = T; 
    constexpr Matrix() : {} 
    ~Matrix(){} 

    constexpr Matrix(const std::array<T, numrows*numcols>& a) : 
     values_(a){} 

    constexpr Matrix(const Matrix& other) : 
     values_(other.values_){ 

    } 

    constexpr const T& operator()(int row, int col) const { 
     return values_[row*numcols+col]; 
    } 

    T& operator()(int row, int col){ 
     return values_[row*numcols+col]; 
    } 

    constexpr int rows() const { 
     return numrows; 
    } 

    constexpr int columns() const { 
     return numcols; 
    } 


private: 
    std::array<T, numrows*numcols> values_{}; 
}; 

विचार एक साधारण मैट्रिक्स वर्ग है, जो मैं कर सकते हैं संकलन समय पर मैट्रिक्स अभिव्यक्तियों का मूल्यांकन करने के लिए छोटे मैट्रिस के लिए उपयोग करें (ध्यान दें कि मैंने अभी तक अतिरिक्त मैट्रिक्स ऑपरेटरों को अतिरिक्त और गुणा के लिए लागू नहीं किया है)।

जब मैं इस प्रकार एक मैट्रिक्स उदाहरण प्रारंभ करने का प्रयास करें:

constexpr std::array<double, 4> a = {1,1,1,1}; 
constexpr Matrix<double, 2, 2> m(a); 

मैं संकलक से निम्न त्रुटि हो रही है (एमएस विजुअल C++ 14):

error: C2127: 'm': illegal initialization of 'constexpr' entity with a non-constant expression 

नोट यकीन है कि मैं क्या हूँ गलत कर रहा है ... इस काम को करने में कोई मदद की सराहना की जाएगी!

+0

हो सकता है कि 'std :: array' एक constexpr प्रतिलिपि निर्माता नहीं है? –

+2

विनाशक की परिभाषा को हटाएं –

+2

एक sidenote के रूप में, सदस्य चर के रूप में 'numrows_' और' numcols_' को स्टोर करने की आवश्यकता नहीं है। चूंकि आपके पास पहले से ही टेम्पलेट पैरामीटर के रूप में मान हैं, बस उनको वापस कर दें। –

उत्तर

13

[basic.types]/p10 कहा गया है कि:

एक प्रकार एक शाब्दिक प्रकार है अगर यह होता है:

  • संभवतः सीवी योग्य void; या

  • एक स्केलर प्रकार; या

  • एक संदर्भ प्रकार; या

  • शाब्दिक प्रकार की एक सरणी; या

  • एक संभवतः सीवी योग्य वर्ग प्रकार (क्लॉज [class]) निम्नलिखित गुण के सभी है:

    • यह एक छोटी सी नाशक है,

    • यह या तो बंद करने का प्रकार (है [expr.prim.lambda]), एक कुल प्रकार ([dcl.init.aggr]), या कम से कम एक कॉन्स्टेक्सर कन्स्ट्रक्टर या कन्स्ट्रक्टर टेम्पलेट (संभवतः एक बेस क्लास से विरासत में मिला ([namespace.udecl]) है जो कि प्रतिलिपि या चालक नहीं है,

    • अगर यह एक संघ है, अपने गैर स्थिर डेटा सदस्यों में से कम से कम एक नॉन-वोलाटाइल शाब्दिक प्रकार का है, और

    • अगर यह एक संघ नहीं है, अपने गैर स्थिर डेटा सदस्यों और आधार के सभी कक्षाएं गैर-अस्थिर शाब्दिक प्रकार के हैं।

जहां [class.dtor]/p5 का कहना है कि:

एक नाशक तुच्छ है अगर यह उपयोगकर्ता के प्रदान की है और अगर नहीं है:

(5।4) - तुच्छ विनाशकर्ता है अपने वर्ग के प्रत्यक्ष आधार वर्ग के सभी, और

(5,6) - - नाशक, virtual नहीं है

(5,5) गैर के सभी के लिए कक्षा के प्रकार (या सरणी) के वर्ग के स्थिर डेटा सदस्य, प्रत्येक कक्षा में एक छोटा विनाशक है।

अन्यथा, विनाशक गैर-तुच्छ है।

दूसरे शब्दों में, Matrix के constexpr उदाहरण घोषित करने के लिए, यह एक शाब्दिक प्रकार होना चाहिए, और एक शाब्दिक प्रकार हो सकता है, इसके नाशक या तो default एड होना चाहिए, या पूरी तरह हटा, तो:

~Matrix() = default; 

या:


                
+0

के लिए अनावश्यक सदस्य चर को हटाकर कोड साफ़ कर दिया है सभी स्पष्टीकरणों के लिए बहुत बहुत धन्यवाद! – BigONotation

+6

मुझे _or_ पसंद है। :-) – skypjack

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

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