Почему std::array::size constexpr с простыми типами (int, double,...), но не std:: vector (GCC)?
следующий код:
std::array<int, 4> arr1;
std::array<float, arr1.size()> arr2;
...компилируется с обоими gcc
и clang
, потому что std::array::size
является constexpr
.
но следующее не компилируется с gcc
(версия 5.3.0 20151204):
std::array<std::vector<int>, 4> arr1;
std::array<std::vector<double>, arr1.size()> arr2;
для меня нет причин, по которым такой код не должен компилироваться, если первый работает, но поскольку я не нашел много сообщений об этом, я не знаю, является ли это gcc
ошибка или clang
продление?
ошибка gcc
(этого я действительно не понимаю... ):
main.cpp: In function 'int main()':
main.cpp:6:46: error: call to non-constexpr function 'constexpr std::array<_Tp, _Nm>::size_type std::array<_Tp, _Nm>::size() const [with _Tp = std::vector<int>; long unsigned int _Nm = 4ul; std::array<_Tp, _Nm>::size_type = long unsigned int]'
std::array<std::vector<double>, arr1.size()> arr2;
^
In file included from main.cpp:1:0:
/usr/local/include/c++/5.3.0/array:170:7: note: 'constexpr std::array<_Tp, _Nm>::size_type std::array<_Tp, _Nm>::size() const [with _Tp = std::vector<int>; long unsigned int _Nm = 4ul; std::array<_Tp, _Nm>::size_type = long unsigned int]' is not usable as a constexpr function because:
size() const noexcept { return _Nm; }
^
/usr/local/include/c++/5.3.0/array:170: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::vector<int>; long unsigned int _Nm = 4ul; std::array<_Tp, _Nm>::size_type = long unsigned int]' is not a literal type
/usr/local/include/c++/5.3.0/array:89:12: note: 'std::array<std::vector<int>, 4ul>' is not literal because:
struct array
^
/usr/local/include/c++/5.3.0/array:89:12: note: 'std::array<std::vector<int>, 4ul>' has a non-trivial destructor
main.cpp:6:46: error: call to non-constexpr function 'constexpr std::array<_Tp, _Nm>::size_type std::array<_Tp, _Nm>::size() const [with _Tp = std::vector<int>; long unsigned int _Nm = 4ul; std::array<_Tp, _Nm>::size_type = long unsigned int]'
std::array<std::vector<double>, arr1.size()> arr2;
^
main.cpp:6:48: note: in template argument for type 'long unsigned int'
std::array<std::vector<double>, arr1.size()> arr2;
^
1 ответов
Я думаю, что это связано с CWG issue 1684. Ранее в constexpr
требования входят:
класс которого a
constexpr
функция является членом должна быть литерального типа
и std::array<std::vector<int>, 4>
и не литеральный тип, и, следовательно, его size()
функция-член не будет constexpr
. Однако новая формулировка допускает constexpr
нестатические функции-члены для небуквальные типов, предполагая, что эти функции отвечают все остальные требования constexpr
(где array<T,N>::size()
четко делает).
в новой формулировке это ошибка gcc. Ранее подано как 66297.