2016-02-12 12 views
5
codice

Esempio test.cpperrore quando si istanzia std :: array utilizzando std :: matrice :: size

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

compilazione con g ++ 4.8.4 (Ubuntu 14,04)

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

dà il seguente messaggio di errore

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; 
             ^

Qualcuno può spiegare questo errore? Perché il primo esempio funziona mentre il secondo non viene compilato?

+0

Definite vittima - hanno visto questa domanda un paio di volte di recente –

+0

Eventuali duplicati di [constexpr ed errore bizzare] (http://stackoverflow.com/questions/9607279/constexpr-and-bizzare-error) – mindriot

+3

Possibile duplicato [Ottenere il numero di elementi in std :: gamma al momento della compilazione] (http://stackoverflow.com/questions/16866033/getting-the-number-of-elements-in-stdarray-at-compile- ora) – sergej

risposta

2

Il tipo std :: string non è un tipo letterale cioè non può essere manipolato come parte di una funzione constexpr al momento della compilazione. Al momento della compilazione, il compilatore tenta di valutare la funzione size() di array_string. Il parametro di funzioni di primo tipo, come potete vedere nel primo errore è impostato a std :: basic_string < char> (aka std :: string); Pertanto, dal momento che std :: string non è un tipo letterale, la funzione non può essere valutata in funzione constexpr al momento della compilazione e si dispone di un errore.

vorrei fare riferimento a quanto segue per saperne di più su constexpr.

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

Vi rimando al seguente per conoscere i tipi di letterali.

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

Infine, provare il seguente codice semplice e vedrete che int e float sono tipi letterali e std :: string non è. Puoi provarlo con altri tipi per vedere quali sono o non sono tipi letterali.

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

Spero che questo aiuti.

John

Problemi correlati