GCC 7.2标准库使用constexpr重载在std :: distance中可能出现constexpr错误

时间:2017-08-20 08:54:37

标签: c++ gcc compiler-errors stl c++17

该函数声明为constexprstd::distance的重载为constexpr。但是当我用gcc7.2编译时,我得到一个我不理解的错误。

在我看来,constexpr std::distance中存在一个错误。 该错误表示它调用的std::__iterator_category(__first));不是constexpr

live example

这是代码和错误

#include <iostream>
#include <algorithm>
#include <iterator>
#include <stdexcept>
#include <array>
#include <string>
#include <cassert>

template<typename It>
constexpr auto max (It first, It last)
{
  auto count = std::distance(first, last);
  if (count == 0)
    throw std::domain_error{"max is undefined on empty range"};
  if (count == 1) return *first;
  auto mid = first + (last - first) / 2;
  return std::max(max(first, mid), max(mid, last));
}

int main()
{
  constexpr std::array<int, 4> vs{1,6,8,3};
  constexpr auto max_of_vs = max(std::cbegin(vs), std::cend(vs));
  assert(max_of_vs == 8);
  std::cout << max_of_vs << std::endl;
  std::array<int, 5> xs{1,9,8,3,6};
  auto max_of_xs = max(std::begin(xs), std::end(xs));
  assert(max_of_xs == 9);
  std::cout << max_of_xs << std::endl;
  //std::array<int, 0> zs{};
  //auto max_of_zs = max(std::begin(zs), std::end(zs)); // throws at runtime
  //assert(max_of_zs == 0);
}

错误:

main.cpp: In function 'int main()':

main.cpp:23:33:   in constexpr expansion of 'max<const int*>(std::cbegin<std::array<int, 4> >(vs), std::cend<std::array<int, 4> >(vs))'

main.cpp:12:29: error: 'constexpr typename std::iterator_traits<_Iterator>::difference_type std::distance(_InputIterator, _InputIterator) [with _InputIterator = const int*; typename std::iterator_traits<_Iterator>::difference_type = long int]' called in a constant expression

   auto count = std::distance(first, last);

                ~~~~~~~~~~~~~^~~~~~~~~~~~~

In file included from /usr/local/include/c++/7.2.0/bits/stl_algobase.h:66:0,

                 from /usr/local/include/c++/7.2.0/bits/char_traits.h:39,

                 from /usr/local/include/c++/7.2.0/ios:40,

                 from /usr/local/include/c++/7.2.0/ostream:38,

                 from /usr/local/include/c++/7.2.0/iostream:39,

                 from main.cpp:1:

/usr/local/include/c++/7.2.0/bits/stl_iterator_base_funcs.h:138:5: note: 'constexpr typename std::iterator_traits<_Iterator>::difference_type std::distance(_InputIterator, _InputIterator) [with _InputIterator = const int*; typename std::iterator_traits<_Iterator>::difference_type = long int]' is not usable as a constexpr function because:

     distance(_InputIterator __first, _InputIterator __last)

     ^~~~~~~~

/usr/local/include/c++/7.2.0/bits/stl_iterator_base_funcs.h:142:33: error: call to non-constexpr function 'typename std::iterator_traits<_Iterator>::iterator_category std::__iterator_category(const _Iter&) [with _Iter = const int*; typename std::iterator_traits<_Iterator>::iterator_category = std::random_access_iterator_tag]'

         std::__iterator_category(__first));

         ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~

0 个答案:

没有答案