c++ - std::reduce 与仿函数
问题描述
我尝试使用std::reduce
仿函数来计算数组中的字符数。GCC 在 MSVC 中编译和工作时出错。链接在这里
#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 错误,因为重要信息不应隐藏在链接后面:
/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>);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
解决方案
我同意dewaffled认为这是一个错误。的libstdc++
实现std::reduce
看起来像这样:
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>);
// ...
}
我无法在标准中找到迭代器value_type
必须可转换为Tp
. 而且,这个要求根本没有必要。如果您删除该静态断言,您的代码将按应有的方式编译。
来自 GCC Bugzilla 的更新
已为 9.5、10.4 和 11.2 修复。
乔纳森·韦克利,2021-06-18
推荐阅读
- django - 如何打印视图返回的上下文添加模板
- ruby-on-rails - 之后的参数部分。丢失(.com)
- javascript - 如何通过确认确认()框来运行一些代码?
- python - 返回一个修改过的树,每个节点都添加了括号
- javascript - 如何在嵌套在数组内的对象中添加项目
- flutter - 从屏幕外部的 SlideTransition
- reactjs - reactjs中的Google-api搜索
- python - 火炬如何在几乎零时间内将两个 10000*10000 矩阵相乘?为什么速度从 349 ms 下降到 999 µs 变化如此之大?
- phpmyadmin - 如何让 lightsail 数据库用户看到在 phpmyadmin 中以 root 身份创建的数据库?
- ssl - 在客户端和服务器(非 HTTPS)之间使用自定义协议时是否需要 SSL 证书?