2016-02-12 86 views
5

實施例代碼TEST.CPP錯誤使用std實例化的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; 
} 

使用g ++編譯4.8.4(Ubuntu的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的和古怪的錯誤]的可能的複製(http://stackoverflow.com/questions/9607279/constexpr-and-bizzare-error) – mindriot

+3

[在編譯時獲取std :: array中元素的數量]的可能重複(http://stackoverflow.com/questions/16866033/getting-the-number-of-elements-in-stdarray-at-compile-時間) – sergej

回答

2

std :: string類型不是字面類型,這意味着它不能在編譯時作爲constexpr函數的一部分進行操作。在編譯時,編譯器會嘗試評估array_string的size()函數。您可以在第一個錯誤中看到的函數第一個類型參數設置爲std :: basic_string < char>(aka std :: string);因此,由於std :: string不是一個文字類型,因此該函數在編譯時不能作爲constexpr函數進行計算,並且出現錯誤。

我會參考以下內容來了解​​有關constexpr的更多信息。

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

我想請您看看下面來了解文字類型。

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

最後,請嘗試以下簡單的代碼,你會看到,int和float是文字類型和std :: string是不是。你可以嘗試用其他類型來看看什麼是或不是文字類型。

#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; 
}         

希望有幫助。

約翰