C++ std::reduce with functor

C++ std::reduce with functor,c++,libstdc++,C++,Libstdc++,我尝试使用带有函子的std::reduce来计算数组中的字符数。GCC在MSVC中编译和工作时出错 #包括 #包括 #包括 #包括 int main() { 数组arr{“米奇”、“米妮”、“杰瑞”}; 结构字符串长度 { 自动运算符() { 返回strlen(l)+r; } 自动运算符() { 返回l+strlen(r); } 自动运算符()(常量字符*l,常量字符*r) { 返回strlen(l)+strlen(r); } 自动运算符() { 返回l+r; } }; std::cout我同意

我尝试使用带有函子的
std::reduce
来计算数组中的字符数。GCC在MSVC中编译和工作时出错

#包括
#包括
#包括
#包括
int main()
{
数组arr{“米奇”、“米妮”、“杰瑞”};
结构字符串长度
{
自动运算符()
{
返回strlen(l)+r;
}
自动运算符()
{
返回l+strlen(r);
}
自动运算符()(常量字符*l,常量字符*r)
{
返回strlen(l)+strlen(r);
}
自动运算符()
{
返回l+r;
}
};

std::cout我同意dewaffled这是一个bug。
std::reduce
libstdc++
如下所示:

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>);
    // ...
}
模板
Tp reduce(先输入,后输入,Tp init,BinOp binary_op){
使用value\u type=typename迭代器\u traits::value\u type;
静态断言(可调用);
静态断言(可转换);
// ...
}
我在迭代器的
值类型
必须转换为
Tp
中找不到一个要求。此外,这个要求根本不是必需的。如果删除静态断言,您的代码应该会很好

从GCC Bugzilla更新

针对9.5、10.4和11.2进行了固定。
乔纳森·韦克利,2021-06-18


看起来像是一个gcc实现错误。另外,它意外地在gcc中以以下形式工作:
std::reduce(std::execution::seq,arr.begin(),arr.end(),size_t{},StringLength()
@dewaffled我不相信这是GCC错误。因为Clang也给出了完全相同的错误。好吧,这是GCC libstdc++错误,GCC和Clang在Godbolt上都使用它。你必须将-stdlib=libc++传递给Clang,使它在Godbolt上实际使用自己的标准库。libstdc++是GNU,libc++是Clang,前者是(出于某种原因)Godbolt上的全局默认值。已提交报告:
/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>);
      |                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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>);
    // ...
}