I tried to use std::reduce
with a functor to calculate the number of characters in an array. GCC gives an error, while it compiles and works in MSVC. link here
#include <iostream>
#include <array>
#include <numeric>
#include <cstring>
int main()
{
std::array arr{ "Mickey","Minnie","Jerry" };
struct StringLength
{
auto operator()(const char* l, size_t r)
{
return strlen(l) + r;
}
auto operator()(size_t l, const char* r)
{
return l + strlen(r);
}
auto operator()(const char* l, const char* r)
{
return strlen(l) + strlen(r);
}
auto operator()(size_t l, size_t r)
{
return l + r;
}
};
std::cout << std::reduce(arr.begin(), arr.end(), size_t{}, StringLength());
// this ^ works in MSVC
}
GCC 10.1 error because important information should not be hidden behind a link:
/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/numeric:
In instantiation of '_Tp std::reduce(_InputIterator, _InputIterator, _Tp, _BinaryOperation)
[with _InputIterator = const char**; _Tp = long unsigned int;
_BinaryOperation = main()::StringLength]':
<source>:29:78: required from here
/opt/compiler-explorer/gcc-10.1.0/include/c++/10.1.0/numeric:263:21: error:
static assertion failed
263 | static_assert(is_convertible_v<value_type, _Tp>);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I agree with dewaffled that this is a bug. The libstdc++
implementation of std::reduce
looks like this:
template<typename InputIt, typename Tp, typename BinOp>
Tp reduce(InputIt first, InputIt last, Tp init, BinOp binary_op) {
using value_type = typename iterator_traits<InputIt>::value_type;
static_assert(is_invocable_r_v<Tp, BinOp&, Tp&, Tp&>);
static_assert(is_convertible_v<value_type, Tp>);
// ...
}
I wasn't able to find a requirement in the standard that iterator's value_type
has to be convertible into Tp
. Moreover, this requirement is not necessary at all. If you remove that static assert, your code will compile just fine as it should.
Update from GCC Bugzilla
Fixed for 9.5, 10.4 and 11.2.
Jonathan Wakely, 2021-06-18
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With