This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of NAD Concepts status.

### 1067. simplified wording for inner_product

Section: 25.10 [numeric.ops] Status: NAD Concepts Submitter: Alisdair Meredith Opened: 2009-03-17 Last modified: 2016-01-28

Priority: Not Prioritized

View all other issues in [numeric.ops].

View all issues with NAD Concepts status.

Discussion:

One of the motivating examples for introducing requirements-aliases was to simplify the wording of the `inner_product` requirements. As the paper adopting the feature and constrained wording for the library went through in the same meeting, it was not possible to make the change at the time. The simpler form should be adopted now though. Similarly, most the other numerical algorithms can benefit from a minor cleanup.

Note that in each case, the second more generalised form of the algorithm does not benefit, as there are already named constraints supplied by the template type parameters.

[ 2009-05-02 Daniel adds: ]

> one part of the suggested resolution suggests the removal of the `MoveConstructible<T>` requirement from `inner_product`. According to 25.10.5 [inner.product]

> > Computes its result by initializing the accumulator `acc` with the initial value `init`

> this step requires at least `MoveConstructible`.

> Therefore I strongly suggest to take this removal back (Note also that the corresponding overload with a functor argument still has the same `MoveConstructible<T>` requirement).

[ Batavia (2009-05): ]

> We agree with the proposed resolution as amended by Daniel's suggestion to restore `MoveConstructible`, reflected in the updated proposed resolution below.

> Move to Tentatively Ready.

Proposed resolution:

Change in 25.10 [numeric.ops] and 25.10.3 [accumulate]:

>     template <InputIterator Iter, MoveConstructible T>
>      requires add = HasPlus<T, Iter::reference>
>            && HasAssign<T, HasPlus<T, Iter::reference> add::result_type>
>      T accumulate(Iter first, Iter last, T init);

Change in 25.10 [numeric.ops] and 25.10.5 [inner.product]:

>     template <InputIterator Iter1, InputIterator Iter2, MoveConstructible T>
>       requires mult = HasMultiply<Iter1::reference, Iter2::reference>
>             && add = HasPlus<T, HasMultiply<Iter1::reference, Iter2::reference> mult::result_type>
>             && HasAssign<
>                  T,
>                  HasPlus<T,
>                          HasMultiply<Iter1::reference, Iter2::reference>::result_type> add::result_type>
>       T inner_product(Iter1 first1, Iter1 last1, Iter2 first2, T init);

Change in 25.10 [numeric.ops] and 25.10.7 [partial.sum]:

>     template <InputIterator InIter, OutputIterator<auto, const InIter::value_type&> OutIter>
>       requires add = HasPlus<InIter::value_type, InIter::reference>
>             && HasAssign<InIter::value_type,
>                          HasPlus<InIter::value_type, InIter::reference> add::result_type>
>             && Constructible<InIter::value_type, InIter::reference>
>       OutIter partial_sum(InIter first, InIter last, OutIter result);

Change in 25.10 [numeric.ops] and 25.10.12 [adjacent.difference]:

>     template <InputIterator InIter, OutputIterator<auto, const InIter::value_type&> OutIter>
>       requires sub = HasMinus<InIter::value_type, InIter::value_type>
>             && Constructible<InIter::value_type, InIter::reference>
>             && OutputIterator<OutIter, HasMinus<InIter::value_type, InIter::value_type> sub::result_type>
>             && MoveAssignable<InIter::value_type>
>       OutIter adjacent_difference(InIter first, InIter last, OutIter result);