C++ 使用std::array::size实例化std::array时出错

C++ 使用std::array::size实例化std::array时出错,c++,arrays,c++11,std,constexpr,C++,Arrays,C++11,Std,Constexpr,示例代码test.cpp #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&

示例代码test.cpp

#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;
}
给出以下错误消息

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;
                                          ^
test.cpp:在函数“int main()”中:
test.cpp:14:39:错误:调用非constexpr函数“constexpr std::array::size_type std::array::size()const[with _Tp=std::basic_string;long unsigned int _Nm=2ul;std::array::size_type=long unsigned int]”
std::数组\u浮点\u错误;
^
在test.cpp中包含的文件中:1:0:
/usr/include/c++/4.8/array:162:7:注意:“constepr std::array::size_type std::array::size()const[with _Tp=std::basic_string;long unsigned int _Nm=2ul;std::array::size_type=long unsigned int]”不能用作constepr函数,因为:
size()常量noexcept{return\u Nm;}
^
/usr/include/c++/4.8/array:162:7:错误:constepr非静态成员函数的封闭类“constepr std::array::size_type std::array::size()const[with _Tp=std::basic_string;long unsigned int_Nm=2ul;std::array::size_type=long unsigned int]”不是文字类型
/usr/include/c++/4.8/array:81:12:注意:“std::array”不是文字,因为:
结构体数组
^
/usr/include/c++/4.8/array:81:12:注意:“std::array”有一个非平凡的析构函数
test.cpp:14:39:错误:调用非constexpr函数“constexpr std::array::size_type std::array::size()const[with _Tp=std::basic_string;long unsigned int _Nm=2ul;std::array::size_type=long unsigned int]”
std::数组\u浮点\u错误;
^
test.cpp:14:40:注意:类型“long unsigned int”的模板参数中
std::数组\u浮点\u错误;
^
test.cpp:14:59:错误:在“;”之前的声明中的类型无效代币
std::数组\u浮点\u错误;
^
test.cpp:9:39:警告:未使用的变量“array\u float\u ok”[-Wunused variable]
std::数组\u浮点\u正常;
^
test.cpp:14:42:警告:未使用的变量“array\u float\u error”[-Wunused variable]
std::数组\u浮点\u错误;
^

有人能解释这个错误吗?为什么第一个示例可以工作而第二个示例不能编译?

类型std::string不是文本类型,这意味着它不能在编译时作为constexpr函数的一部分进行操作。在编译时,编译器尝试计算数组_字符串的size()函数。在第一个错误中可以看到,函数的第一个类型参数设置为std::basic_string(又称std::string);因此,由于std::string不是文本类型,因此无法在编译时将该函数作为constexpr函数进行计算,因此会出现错误

我想让您参考以下内容,以了解更多有关constexpr的信息

我建议您参考以下内容来了解文字类型

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

最后,尝试下面的简单代码,您将看到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;
}                                  
#包括
int main(int argc,字符**argv)
{ 

std::cout Definite dupe-最近已经多次看到这个问题的可能重复我不完全理解链接问题中给出的答案。它提到“a1不是constexpr值”(因为std::string不能是constexpr)在我的例子中,它对应于array_string。这是否意味着array_int隐式地是一个constexpr值(因为我没有将它指定为constexpr)?@simon这看起来像是gcc中的编译器错误;我使用g++5.1.1和相同的结果对它进行了测试;clang++3.5.0正确地编译了这段代码。
size()
方法应为constexpr,无论存储在std::array中的类型如何。