2016-02-12 85 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; 
}         

希望有帮助。

约翰