c++ boost::bind vs clojure partial function
c++ boost::bind vs clojure partial function
C++ Boost bind 库和 Clojure 的部分函数非常相似。例如:
int x = 8;
bind(std::less<int>(), _1, 9)(x); // x < 9
这类似于clojure的部分函数:
((partial > 9) 8)
不同之处在于,partial
只允许绑定前 n 个参数,而 boost::bind
允许占位符指示哪些参数已绑定,哪些参数未绑定。所以boost::bind
实际上更通用和有用:
bind(f, _2, _1)(x, y); // f(y, x)
bind(g, _1, 9, _1)(x); // g(x, 9, x)
我想知道在 clojure(或 clojure-contrib)中是否有类似于boost::bind
的东西?为什么部分没有像boost::bind
那样写得更普遍(和有用)?
这是 Clojure 的一个相当常见的问题,更常见的是线程宏 -> 和 ->> 为什么它们也不允许任意占位符。
在我看来,给出的理由在这里也适用:惯用的 Clojure 函数通常分解为适合单独提供第一个或最后一个参数的函数,而不是混合的函数。
换句话说,开发人员通常尝试对函数进行编码,以便它们适合 ->、->> 和/或部分。
给定匿名函数的读取器宏,对于不太惯用的情况,在需要时创建占位符版本相当容易:
#(f %2 %1) ;; bind(f, _2, _1)
#(g % 9 %) ;; bind(g, _1, 9, _1)
就像肖恩说的,partial
解决了一个更具体的问题,一般来说,lambdas是惯用的解决方案。也就是说,如果你绝望了,你总是可以自己bind
:
(defmacro bind
[bound-function & args]
(let [; helper function to parse actual argument symbols
get-symbols (fn [s] (map second s)),
; help function to get the placeholder arguments
get-placeholders (fn [s] (filter first s))
; collection of arguments and whether they're placeholders
bound-args (map (fn [arg]
(if (= arg '_)
; for placeholders, generate a new symbol
[true (gensym)]
; otherwise, use the provided argument as-is
[false arg]))
args)]
`(fn [~@(get-symbols (get-placeholders bound-args))]
(~bound-function ~@(get-symbols bound-args)))))
其用途如下:
((bind > 9 _) 8) ; true
((bind > _ _) 9 8 ) ; true
有一个瑞士箭头库,允许各种其他参数线程/绑定方案。但是,其中有很多选项,优化函数的参数以最好地使用 -> 和 ->> 宏的首选解决方案,如果不可能,请使用匿名函数作为最简单的通用解决方案。
相关文章:
- "error: no matching function for call to"构造函数错误
- 调用专用模板时出错"no matching function for call to [...]"
- 库函数需要一个 std::function<void(void)>,如何传入类函数?
- Confusion: decltype vs std::function
- 为什么 std::function 可以作为 std::not2 的参数?
- 'max'匹配'std::function<const int &(const int &, const int &)>'无过载
- 传递给std::function template的template参数究竟代表什么
- 将带有unique_ptr的可变 lambda 传递给 const&std::function
- 绑定派生类方法C++从实例范围之外的分隔 std::function 变量调用
- "no matching function for call to 'Vector::Vector'"错误
- 如何在向量中删除 std::function<void()>?
- 不断"Attempting to reference a deleted function"
- 将函数包装器转换为 std::function
- 类型擦除的std::function与虚拟函数调用的开销
- C++ std::function 对于类 exept 的所有实例都是空的(只有 Visual2019 编译器问题)
- 如果模板没有可变参数,则 Lambda 被推导出为 std::function
- 我在 ifstream input_file(文件名)行中收到错误"no matching function to call";
- 模板规范获取'Ambiguous call to overloaded function'
- c++ boost::bind vs clojure partial function
- boost::bind & boost::function with partial args