移除std::binary_function与result_type的C++代码改造求助
替换std::binary_function的result_type(C++11兼容方案)
问题描述
我正在将一个废弃的开源库升级到C11和C17标准。原库使用了std::binary_function及其result_type,但这些特性在C11中被弃用,C17中已被移除。我已经移除了std::binary_function(以及std::unary_function),但不知道如何替换以下代码中的result_type:
template<class R, int D, class F> static Vector<typename F::result_type, D> apply(const F &func, const VRD &v) { Vector<typename F::result_type, D> out; _apply(func, v, out); return out; }
我试过用auto替代Vector<typename F::result_type, D>,但设置为C11的编译器报错,提示返回值auto是C14才引入的特性。F是泛型函子,请问在未知result_type的情况下如何重写这段代码?
解决方案
方案1:C++11原生兼容写法
C++11提供了std::result_of模板来推导可调用对象的返回类型,完全可以替代F::result_type。需要先包含<type_traits>头文件,修改后的代码如下:
#include <type_traits> template<class R, int D, class F> static Vector<typename std::result_of<F(R)>::type, D> apply(const F &func, const VRD &v) { using ResultType = typename std::result_of<F(R)>::type; Vector<ResultType, D> out; _apply(func, v, out); return out; }
这里std::result_of<F(R)>::type会自动推导func接收R类型参数时的返回类型,和原代码中F::result_type的作用完全一致。
方案2:同时兼容C11和C17
由于std::result_of在C++17中被弃用,官方推荐使用std::invoke_result,可以通过条件编译实现跨版本兼容:
#include <type_traits> template<class R, int D, class F> static Vector< #if __cplusplus >= 201703L std::invoke_result_t<F, R> #else typename std::result_of<F(R)>::type #endif , D> apply(const F &func, const VRD &v) { using ResultType = #if __cplusplus >= 201703L std::invoke_result_t<F, R> #else typename std::result_of<F(R)>::type #endif ; Vector<ResultType, D> out; _apply(func, v, out); return out; }
std::invoke_result_t是C++17新增的别名模板,写法比std::result_of更简洁,不需要嵌套::type。
注意事项
std::result_of的参数格式是F(ArgTypes...),这里的R必须和func实际接收的参数类型匹配,否则会导致类型推导失败。- 如果
_apply函数是对v的每个元素调用func,那么R应该就是VRD容器中元素的类型,这个推导逻辑是准确的。
内容的提问来源于stack exchange,提问作者Rob McDonald
相关产品推荐
相关产品推荐

