无法编译 std::reduce 调用,而 std::累积调用编译相同的参数
Can't compile std::reduce call, while std::accumulate call compiles on the same arguments
我一直在尝试使用c++17
的std::reduce
算法。据说,它应该支持std::accumulate
支持的相同 API,但是当使用--std=c++17
在clang++-9.0
和gcc-9.2
中编译时,对std::accumulate
的调用编译成功,而对std::reduce
的调用则不然。
到目前为止,我尝试了几件事:
- 定义调用内部和外部的
lambda
- 使用
std::reduce<...>
语法显式指定类型 - 将重载与执行策略参数结合使用
#include <execution>
出现错误
下面是一个示例代码,它使用std::reduce
和std::accumulate
对std::vector
中的字符串长度求和:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <numeric>
int main() {
auto op = [](auto acc, auto val) {
return acc + val.size();
};
std::vector<std::string> v = {"a", "bb", "ccc", "dddd"};
int a = std::reduce(v.begin(), v.end(), 0, op);
int b = std::accumulate(v.begin(), v.end(), 0, op);
return 0;
}
编译失败,在调用std::reduce
的行中,clang-9.0.0
的以下输出:
<source>:12:13: error: no matching function for call to 'reduce'
int a = std::reduce(v.begin(), v.end(), 0, op);
^~~~~~~~~~~
/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/pstl/glue_numeric_defs.h:26:1: note: candidate template ignored: deduced conflicting types for parameter '_ForwardIterator' ('__gnu_cxx::__normal_iterator<std::__cxx11::basic_string<char> *, std::vector<std::__cxx11::basic_string<char>, std::allocator<std::__cxx11::basic_string<char> > > >' vs. 'int')
reduce(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Tp __init);
^
/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/pstl/glue_numeric_defs.h:21:1: note: candidate function template not viable: requires 5 arguments, but 4 were provided
reduce(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Tp __init,
^
/opt/compiler-explorer/gcc-9.2.0/lib/gcc/x86_64-linux-gnu/9.2.0/../../../../include/c++/9.2.0/pstl/glue_numeric_defs.h:31:1: note: candidate function template not viable: requires 3 arguments, but 4 were provided
reduce(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last);
^
1 error generated.
以及来自gcc-9.2
的以下输出:
<source>: In function 'int main()':
<source>:12:50: error: no matching function for call to 'reduce(std::vector<std::__cxx11::basic_string<char> >::iterator, std::vector<std::__cxx11::basic_string<char> >::iterator, int, main()::<lambda(auto:1, auto:2)>&)'
12 | int a = std::reduce(v.begin(), v.end(), 0, op);
| ^
In file included from /opt/compiler-explorer/gcc-9.2.0/include/c++/9.2.0/numeric:229,
from <source>:5:
/opt/compiler-explorer/gcc-9.2.0/include/c++/9.2.0/pstl/glue_numeric_defs.h:21:1: note: candidate: 'template<class _ExecutionPolicy, class _ForwardIterator, class _Tp, class _BinaryOperation> __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> std::reduce(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Tp, _BinaryOperation)'
21 | reduce(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Tp __init,
| ^~~~~~
/opt/compiler-explorer/gcc-9.2.0/include/c++/9.2.0/pstl/glue_numeric_defs.h:21:1: note: template argument deduction/substitution failed:
<source>:12:50: note: deduced conflicting types for parameter '_ForwardIterator' ('__gnu_cxx::__normal_iterator<std::__cxx11::basic_string<char>*, std::vector<std::__cxx11::basic_string<char> > >' and 'int')
12 | int a = std::reduce(v.begin(), v.end(), 0, op);
| ^
In file included from /opt/compiler-explorer/gcc-9.2.0/include/c++/9.2.0/numeric:229,
from <source>:5:
/opt/compiler-explorer/gcc-9.2.0/include/c++/9.2.0/pstl/glue_numeric_defs.h:26:1: note: candidate: 'template<class _ExecutionPolicy, class _ForwardIterator, class _Tp> __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, _ForwardIterator2> std::reduce(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Tp)'
26 | reduce(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Tp __init);
| ^~~~~~
/opt/compiler-explorer/gcc-9.2.0/include/c++/9.2.0/pstl/glue_numeric_defs.h:26:1: note: template argument deduction/substitution failed:
<source>:12:50: note: deduced conflicting types for parameter '_ForwardIterator' ('__gnu_cxx::__normal_iterator<std::__cxx11::basic_string<char>*, std::vector<std::__cxx11::basic_string<char> > >' and 'int')
12 | int a = std::reduce(v.begin(), v.end(), 0, op);
| ^
In file included from /opt/compiler-explorer/gcc-9.2.0/include/c++/9.2.0/numeric:229,
from <source>:5:
/opt/compiler-explorer/gcc-9.2.0/include/c++/9.2.0/pstl/glue_numeric_defs.h:31:1: note: candidate: 'template<class _ExecutionPolicy, class _ForwardIterator> __pstl::__internal::__enable_if_execution_policy<_ExecutionPolicy, typename std::iterator_traits<_II>::value_type> std::reduce(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator)'
31 | reduce(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last);
| ^~~~~~
/opt/compiler-explorer/gcc-9.2.0/include/c++/9.2.0/pstl/glue_numeric_defs.h:31:1: note: template argument deduction/substitution failed:
<source>:12:50: note: deduced conflicting types for parameter '_ForwardIterator' ('__gnu_cxx::__normal_iterator<std::__cxx11::basic_string<char>*, std::vector<std::__cxx11::basic_string<char> > >' and 'int')
12 | int a = std::reduce(v.begin(), v.end(), 0, op);
| ^
实际上,reduce
和accumulate
之间的区别之一是执行策略支持。如果不需要执行策略,可以调用accumulate
。因此,带有std::execution::seq
的代码使用gcc-trunk
成功编译:https://godbolt.org/z/ERxU_q
正如@Vittorio Romeo评论的那样,这可能是libstc++
中的一个错误或尚未实现的功能,可以通过切换到libc++
来使用它-libstd=libc++
相关文章:
- 为什么 std::unique 不调用 std::sort?
- 在 C++20 之前,在带有常量或引用字段的"A"上调用 'std::vector<A>
- C++ 类型的参数与 void (__cdecl*)(void) 类型的参数不兼容,当调用 std::atexit()
- 在调用 std::bind 的产品后意外调用析构函数
- 在抛出 what() 的实例后调用'std::logic_error'终止:basic_string::_M_construct 空无效
- 有没有办法扩展和调用 std::functions 的元组?
- 调用std::函数成员时内存损坏
- 如何在C++03中用自定义谓词调用std::unique
- 未调用 std::unique_ptr 中的自定义删除器
- 从多个线程调用 std::shuffle
- 由于调用 std::condition_variable 后参数无效而导致应用程序崩溃
- 访问并调用 std::function 的变体
- 错误:调用 std::thread 没有匹配函数
- 为什么调用shared_from_this调用 std::终止
- C++天鹅座的错误;没有用于调用"std::basic_fstream..."的匹配函数
- 错误:调用"std::vector<:vector<int>>::p ush_back(std::vector<std::__cxx11::basic_string<
- 防止线程在处理异常后在分离时调用 std::terminate()
- C++线程中调用 std::terminate 时程序返回代码
- 如果从类成员初始值设定项引发的异常调用 std::terminate()
- 线程是否真的在调用 std::future::get() 后启动