On Thu, 27 Jun 2019 at 19:55, Ed Smith-Rowland via libstdc++
<libstd...@gcc.gnu.org> wrote:
> > I don't think this will work in a constant expression:
> >
> > ?? /// Assign @p __new_val to @p __obj and return its previous value.
> > ?? template <typename _Tp, typename _Up = _Tp>
> > +?????? _GLIBCXX20_CONSTEXPR
> > ?????? inline _Tp
> > ?????? exchange(_Tp& __obj, _Up&& __new_val)
> > ?????? { return std::__exchange(__obj, std::forward<_Up>(__new_val)); }
> >
> > Because std::__exchange hasn't been marked constexpr. The test passes
> > because it doesn't call it in a context that requires constant
> > evaluation:
> >
> > ??const auto x = std::exchange(e, pi);
> Derp.
> >
> > I see the same problem in other tests too:
> >
> > +?? constexpr std::array<int, 12> car{{0, 1, 2, 3, 4, 5, 6, 6, 8, 9, 9,
> > 11}};
> > +
> > +?? const auto out0x = std::adjacent_find(car.begin(), car.end());
> > +
> > +?? const auto out1x = std::adjacent_find(car.begin(), car.end(),
> > +?????????????????????????????????????? std::equal_to<int>())
>
> I will go through all the tests and make sure that some nontrivial
> calculation is done that contributes to a final bool return.?? And clean
> up the mess.?? I did this in chunk 2 but I guess I left a lot of chunk 1.

As was the case with the iterator patch, it's not a question of doing
a nontrivial calculation, but
a question of initializing a constexpr variable with the result. (Yeah
sure a non-type template
argument would also work but eurgh). Then, and only then, have we
proven that the code
works in a constexpr context. Initializing a const doesn't do that.
constinit would, but that's
C++20.

Reply via email to