2016-02-12 12 views
5

Beispiel Code test.cppFehler beim Instanziieren std :: array std :: array :: Größe

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

Kompilieren mit g ++ 4.8.4 (Ubuntu 14,04)

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

gibt die folgende Fehlermeldung

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

Kann jemand diesen Fehler erklären? Warum funktioniert das erste Beispiel, während das zweite nicht kompiliert wird?

+0

Definite Betrogene - haben diese Frage ein paar Mal gesehen vor kurzem –

+0

Mögliche Duplikat [constexpr und bizzare Fehler] (http://stackoverflow.com/questions/9607279/constexpr-and-bizzare-error) – mindriot

+3

Mögliches Duplikat von [Abrufen der Anzahl der Elemente in std :: array zur Kompilierzeit] (http://stackoverflow.com/questions/16866033/getting-the-number-of-elements-in-stdarray-at-compile- Zeit) – sergej

Antwort

2

Der Typ std :: string ist kein Literaltyp, was bedeutet, dass er nicht als Teil einer constexpr-Funktion zur Kompilierzeit manipuliert werden kann. Zur Kompilierzeit versucht der Compiler, die Funktion size() der array_string auszuwerten. Der Parameter functions first type, wie Sie im ersten Fehler sehen können, wird auf std :: basic_string gesetzt < char> (aka std :: string); Da std :: string kein literaler Typ ist, kann die Funktion daher nicht zur Compilierzeit als conexpr-Funktion ausgewertet werden, und Sie haben einen Fehler.

Ich würde Sie auf das Folgende verweisen, um mehr über constexpr zu erfahren.

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

Ich möchte Sie auf die folgenden beziehen über wörtliche Arten zu lernen.

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

schließlich die folgenden einfachen Code versuchen, und Sie werden, dass int und float sind wörtliche Typen und std :: string zu sehen ist nicht. Sie können es mit anderen Typen ausprobieren, um zu sehen, ob es sich um literale Typen handelt oder nicht.

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

Hoffe, dass hilft.

John