2015-05-11 3 views
7

मैं नीचे दिए गए कोड, कि मूल रूप से संकलन समय पर एक std::array<> में एक std::integer_sequence<> नक्शे है संकलन नहीं करता है:क्यों स्थिरांक संदर्भ कार्यों द्वारा constexpr वस्तु गुजर, लेकिन मूल्य द्वारा

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

template<int...Is> 
constexpr auto make_array(const std::integer_sequence<int, Is...>& param) // this works */ 
// constexpr auto make_array(std::integer_sequence<int, Is...> param) // doesn't compile 
{ 
    return std::array<int, sizeof...(Is)> {Is...}; 
} 

int main() 
{ 
    constexpr std::integer_sequence<int, 1,2,3,4> iseq; 

    // If I pass by value, error: the value of 'iseq' is not usable in a constant expression 
    constexpr auto arr = make_array(iseq); 

    for(auto elem: arr) 
     std::cout << elem << " "; 
} 

कोड ठीक काम करता है जब भी make_arrayconst -reference द्वारा इसकी तर्क लेता है। जब भी मैं इसे मूल्य से गुजरने की कोशिश करता हूं, जैसे टिप्पणी पंक्ति में, यह एक त्रुटि थूकता है:

error: the value of 'iseq' is not usable in a constant expression

constexpr auto arr = make_array(iseq); 

यह क्यों है? पैरामीटर iseq निश्चित रूप से निरंतर अभिव्यक्ति है, मैं इसे make_array पर क्यों नहीं भेज सकता?

#include <iostream> 
#include <utility> 

struct Foo 
{ 
    int _m; 
    constexpr Foo(int m): _m(m){}; 
}; 

constexpr Foo factory_foo(int m) 
{ 
    return Foo{m}; 
} 

constexpr Foo copy_foo(Foo foo) 
{ 
    return foo; 
} 

int main() 
{ 
    constexpr Foo cxfoo = factory_foo(42); 
    constexpr Foo cpfoo = copy_foo(cxfoo); 
} 

संपादित

मैं macports से जी ++ 5.1 का उपयोग कर रहा:

उदाहरण के लिए, नीचे दिए गए कोड अपेक्षा के मूल्य से गुजर काम करता है। बजना ++ 3.5 का उपयोग करना, मैं भी कोड है कि ++ (const संदर्भ के साथ) जी के साथ संकलित के लिए एक त्रुटि संदेश मिलता है:

error: default initialization of an object of const type 'const std::integer_sequence' requires a user-provided default constructor

इसलिए मुझे लगता है कि एक उपयोगकर्ता द्वारा प्रदान की डिफ़ॉल्ट निर्माता की कमी के साथ कुछ समस्या है, लेकिन कम से इस बिंदु पर मैं वास्तव में समझ नहीं पा रहा हूं कि क्या हो रहा है।

+0

कौन सा कंपाइलर और संस्करण (ओं)। –

+0

@ShafikYaghmour g ++ 5.1, जल्द ही क्लैंग पर आज़माएगा। अद्यतन संपादन देखें, clang ++ 'const' संदर्भ से गुज़रने के मामले में भी एक त्रुटि थूक रहा है। मैं शायद निरंतर अभिव्यक्तियों में डिफ़ॉल्ट-ctors के बारे में कुछ याद कर रहा हूँ। – vsoftco

उत्तर

5

आप iseq पर प्रारंभकर्ता खो रहे हैं। के रूप में कोलंबो उसकी comment और answer में पता चलता है, बस प्रारंभ किया जा रहा insufficent है, इसके अलावा

A constexpr specifier used in an object declaration declares the object as const . Such an object shall have literal type and shall be initialized. If it is initialized by a constructor call, that call shall be a constant expression (5.20). Otherwise, or if a constexpr specifier is used in a reference declaration, every fullexpression that appears in its initializer shall be a constant expression. [ Note: Each implicit conversion used in converting the initializer expressions and each constructor call used for the initialization is part of such a full-expression. —end note ]
[ Example:

struct pixel { 
    int x, y; 
}; 
constexpr pixel ur = { 1294, 1024 }; // OK 
constexpr pixel origin;    // error: initializer missing 

—end example ]

: आप इसे जोड़ने के लिए:

constexpr std::integer_sequence<int, 1,2,3,4> iseq{}; 
                ^^ 

[dcl.constexpr] से। एक उपयोगकर्ता द्वारा प्रदान की निर्माता भी आवश्यक है, [dcl.init] के अनुसार:

If a program calls for the default initialization of an object of a const-qualified type T , T shall be a class type with a user-provided default constructor.

यह सबसे अधिक प्रासंगिक अनुभाग एक constepxr वस्तु के लिए (dcl.constexpr) आवश्यकताओं की एक अधूरी वर्णन करने के लिए एक छोटे से अजीब है घोषणा।

+0

डर्न !!!! यह एक आसान फिक्स था :) तो मुझे लगता है कि जी ++ में एक बग है। यह केवल 'आईएसईक्यू' की परिभाषा की जांच करने के लिए मेरे दिमाग को पार नहीं किया, जिसके लिए क्लैंग ++ एक त्रुटि थूकता। – vsoftco

+0

जब मैंने निहित कॉन्स चीज के बारे में चेक किया तो उद्धरण देखा, +1 – Columbo

+0

@ कोल्लमबो जी ++ के लिए बग की रिपोर्ट करेगा (यदि यह पहले से ही रिपोर्ट नहीं किया गया है) – vsoftco

6

If a program calls for the default initialization of an object of a const-qualified type T , T shall be a class type with a user-provided default constructor.

हालांकि, integer_sequence किसी भी उपयोगकर्ता द्वारा प्रदान की कंस्ट्रक्टर्स नहीं है, और constexpr चर के लिए const का तात्पर्य है, तो आप एक प्रारंभकर्ता बिना उस प्रकार के constexpr वस्तु को परिभाषित नहीं कर सकते हैं।
प्रारंभकर्ता makes it compile on Clang जोड़ना।

+0

धन्यवाद, मैंने आज कुछ सीखा! – vsoftco

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