C++17环境下std::transform_reduce替代实现方案咨询
问题原因
你遇到的问题并非CMake配置错误,而是GCC 8.3.0对C++17标准库的实现不完整。虽然C++17标准确实定义了std::transform_reduce的多参数重载(即你使用的(begin, end, init, binary_op, unary_op)版本),但GCC 8.x系列并未实现这个特定签名,该重载直到GCC 9才被完整加入标准库实现中。
替代方案
以下两种方案均可在不改变程序高层行为的前提下解决编译问题:
方案1:用std::accumulate改写逻辑
std::accumulate是C++17完全支持的算法,可以直接模拟你当前transform_reduce的行为——先转换每个元素,再按指定规则累加。改写后的代码如下:
auto addresses_string = std::accumulate( localAddresses.begin(), localAddresses.end(), std::string(""), [](const std::string& a, const InetAddress& addr) { return a + " | " + addr.str(); });
这段代码的执行逻辑与原transform_reduce完全一致:
- 若
localAddresses为空,返回初始空字符串 - 若不为空,从初始空字符串开始,依次将每个
InetAddress转换为字符串后,通过" | "拼接至结果
方案2:自定义实现缺失的transform_reduce重载
如果你想保留原代码的调用形式,可自行实现该版本的transform_reduce,并通过编译器版本判断来兼容:
#include <iterator> // 仅针对GCC 8.3.0及更早版本启用自定义实现 #if (__GNUC__ == 8 && __GNUC_MINOR__ <= 3) template <typename InputIterator, typename T, typename BinaryOperation, typename UnaryOperation> T transform_reduce(InputIterator first, InputIterator last, T init, BinaryOperation binary_op, UnaryOperation unary_op) { for (; first != last; ++first) { init = binary_op(std::move(init), unary_op(*first)); } return init; } #else // 其他编译器版本直接使用标准库实现 using std::transform_reduce; #endif
之后原代码的std::transform_reduce调用可保持不变,编译时会自动适配:在GCC 8.3.0下使用自定义实现,其他支持该重载的编译器则使用标准库版本。
内容的提问来源于stack exchange,提问作者Amir Rasti
相关产品推荐
相关产品推荐

