2016-02-12 3 views
5

उदाहरण कोड test.cppसमय त्रुटि instantiating std :: सरणी एसटीडी का उपयोग कर :: सरणी :: आकार

#include <array> 
#include <string> 

int main() 
{ 
    // OK 
    const std::array<int, 2> array_int = {42, 1337}; 

    std::array<float, array_int.size()> array_float_ok; 

    // Error 
    const std::array<std::string, 2> array_string = {"foo", "bar"}; 

    std::array<float, array_string.size()> array_float_error; 

    return 0; 
} 

जी के साथ संकलन ++ 4.8.4 (उबंटू 14,04)

g++ -Wall -std=c++0x test.cpp -o test 

निम्नलिखित देता है त्रुटि संदेश

test.cpp: In function ‘int main()’: 
test.cpp:14:39: error: call to non-constexpr function ‘constexpr std::array<_Tp, _Nm>::size_type std::array<_Tp, _Nm>::size() const [with _Tp = std::basic_string<char>; long unsigned int _Nm = 2ul; std::array<_Tp, _Nm>::size_type = long unsigned int]’ 
    std::array<float, array_string.size()> array_float_error; 
            ^
In file included from test.cpp:1:0: 
/usr/include/c++/4.8/array:162:7: note: ‘constexpr std::array<_Tp, _Nm>::size_type std::array<_Tp, _Nm>::size() const [with _Tp = std::basic_string<char>; long unsigned int _Nm = 2ul; std::array<_Tp, _Nm>::size_type = long unsigned int]’ is not usable as a constexpr function because: 
     size() const noexcept { return _Nm; } 
    ^
/usr/include/c++/4.8/array:162:7: error: enclosing class of constexpr non-static member function ‘constexpr std::array<_Tp, _Nm>::size_type std::array<_Tp, _Nm>::size() const [with _Tp = std::basic_string<char>; long unsigned int _Nm = 2ul; std::array<_Tp, _Nm>::size_type = long unsigned int]’ is not a literal type 
/usr/include/c++/4.8/array:81:12: note: ‘std::array<std::basic_string<char>, 2ul>’ is not literal because: 
    struct array 
      ^
/usr/include/c++/4.8/array:81:12: note: ‘std::array<std::basic_string<char>, 2ul>’ has a non-trivial destructor 
test.cpp:14:39: error: call to non-constexpr function ‘constexpr std::array<_Tp, _Nm>::size_type std::array<_Tp, _Nm>::size() const [with _Tp = std::basic_string<char>; long unsigned int _Nm = 2ul; std::array<_Tp, _Nm>::size_type = long unsigned int]’ 
    std::array<float, array_string.size()> array_float_error; 
            ^
test.cpp:14:40: note: in template argument for type ‘long unsigned int’ 
    std::array<float, array_string.size()> array_float_error; 
             ^
test.cpp:14:59: error: invalid type in declaration before ‘;’ token 
    std::array<float, array_string.size()> array_float_error; 
                 ^
test.cpp:9:39: warning: unused variable ‘array_float_ok’ [-Wunused-variable] 
    std::array<float, array_int.size()> array_float_ok; 
            ^
test.cpp:14:42: warning: unused variable ‘array_float_error’ [-Wunused-variable] 
    std::array<float, array_string.size()> array_float_error; 
             ^

क्या कोई इस त्रुटि को समझा सकता है? दूसरा उदाहरण क्यों काम करता है जबकि दूसरा संकलन नहीं करता है?

+0

निश्चित शिकार - इस सवाल कई बार हाल ही में देखा है –

+0

[constexpr और bizzare त्रुटि] की संभावित डुप्लिकेट (http://stackoverflow.com/questions/9607279/constexpr-and-bizzare-error) – mindriot

+3

संभावित डुप्लिकेट [संकलन समय पर std :: सरणी में तत्वों की संख्या प्राप्त करना] (http://stackoverflow.com/questions/16866033/getting-the-number-of-elements-in-stdarray-at-compile- समय) – sergej

उत्तर

2

प्रकार std :: स्ट्रिंग एक शाब्दिक प्रकार नहीं है जिसका अर्थ यह है कि इसे संकलन समय पर कॉन्स्टेक्स फ़ंक्शन के हिस्से के रूप में नहीं बदला जा सकता है। संकलन समय पर, कंपाइलर array_string के आकार() फ़ंक्शन का मूल्यांकन करने का प्रयास करता है। फ़ंक्शंस पहले टाइप पैरामीटर जैसा कि आप पहली त्रुटि में देख सकते हैं std :: basic_string < char> (aka std :: string) पर सेट है; इसलिए, चूंकि std :: स्ट्रिंग एक शाब्दिक प्रकार नहीं है, इसलिए फ़ंक्शन को संकलन समय पर कॉन्स्टेक्स फ़ंक्शन के रूप में मूल्यांकन नहीं किया जा सकता है और आपको कोई त्रुटि है।

मैं आपको constexpr के बारे में अधिक जानने के लिए निम्नलिखित में संदर्भित करता हूं।

http://en.cppreference.com/w/cpp/language/constexpr

मैं शाब्दिक प्रकार के बारे में जानने के लिए निम्नलिखित का उल्लेख होगा।

http://en.cppreference.com/w/cpp/concept/LiteralType

अंत में, निम्नलिखित सरल कोड कोशिश करते हैं और आपको लगता है कि पूर्णांक और नाव शाब्दिक प्रकार और एसटीडी हैं देखेंगे :: स्ट्रिंग नहीं है। आप अन्य प्रकारों के साथ यह देखने के लिए कोशिश कर सकते हैं कि शाब्दिक प्रकार क्या हैं या नहीं।

#include <iostream> 
int main(int argc, char** argv) 
{ 
    std::cout << std::is_literal_type<int>::value << std::endl; 
    std::cout << std::is_literal_type<float>::value << std::endl; 
    std::cout << std::is_literal_type<std::string>::value << std::endl; 
    return 0; 
}         

आशा है कि मदद करता है।

जॉन

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