- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试根据作为参数传递给它的 lambda 的元数来专门化模板函数。这是我想出的解决方案:
template<typename Function, bool>
struct helper;
template<typename Function>
struct helper<Function, false>
{
auto operator()(Function&& func)
{
std::cout << "Called 2 argument version.\n";
return func(1, 2);
}
};
template<typename Function>
struct helper<Function, true>
{
auto operator()(Function&& func)
{
std::cout << "Called 3 argument version.\n";
return func(1, 2, 3);
}
};
template<typename T>
struct B
{
T a;
const T someVal() const { return a; }
};
template<typename Function, typename T>
auto higherOrderFun(Function&& func, const T& a)
{
return helper<Function, std::is_invocable<Function, decltype(a.someVal()), decltype(a.someVal()), decltype(a.someVal())>::value>{}(std::forward<Function>(func));
}
int main()
{
B<int> b;
std::cout << higherOrderFun([](auto x, auto y) {return x+y; }, b) << "\n";
std::cout << higherOrderFun([](auto x, auto y, auto z) {return x + y+z; }, b) << "\n";
return 0;
}
有没有办法以更优雅的方式实现这一点?我看过这个:Arity of a generic lambda
但是,最新的解决方案 (florestan's) 将所有参数转换为 aribtrary_t
,因此必须将它们转换回每个 lambda 内部,我认为这并不理想。理想情况下,我希望直接使用 SFINAE 专门化模板化 higherOrderFun
,但实际上我使用了一个辅助类来实现它。有没有更直接的方法?例如,将 SFINAE 直接应用于 higherOrderFun
而不依赖于 helper
类?这样做的重点是不必将 higherOrderFun
更改为 higherOrderFun2
和 higherOrderFun3
,而是让编译器从 lambda 中推断出正确的特化和给定的参数 (const T& a
)。
我应该提一下,我也不关心函数参数的类型——只关心它们的数量,所以我会把 decltype(a.someVal())
改成 auto
在我的示例中,如果可能的话(也许有一种方法可以避免显式定义类型?)。
最佳答案
以下模板为我提供了 lambda 的参数数量,a std::function
,或一个普通的函数指针。这似乎涵盖了所有基础知识。所以,你专注于n_lambda_parameters<T>::n
,并将其插入您的模板。根据您的具体用例,您可能需要使用 std::remove_reference_t
提供的工具或 std::decay_t
, 包装这个。
使用 g++ 9 测试。需要 std::void_t
来自 C++17,大量模拟 std::void_t
的例子pre C++17 可以在别处找到...
#include <functional>
// Plain function pointer.
template<typename T> struct n_func_parameters;
template<typename T, typename ...Args>
struct n_func_parameters<T(Args...)> {
static constexpr size_t n=sizeof...(Args);
};
// Helper wrapper to tease out lambda operator()'s type.
// Tease out closure's operator()...
template<typename T, typename> struct n_extract_callable_parameters;
// ... Non-mutable closure
template<typename T, typename ret, typename ...Args>
struct n_extract_callable_parameters<T, ret (T::*)(Args...) const> {
static constexpr size_t n=sizeof...(Args);
};
// ... Mutable closure
template<typename T, typename ret, typename ...Args>
struct n_extract_callable_parameters<T, ret (T::*)(Args...)> {
static constexpr size_t n=sizeof...(Args);
};
// Handle closures, SFINAE fallback to plain function pointers.
template<typename T, typename=void> struct n_lambda_parameters
: n_func_parameters<T> {};
template<typename T>
struct n_lambda_parameters<T, std::void_t<decltype(&T::operator())>>
: n_extract_callable_parameters<T, decltype(&T::operator())> {};
#include <iostream>
void foo(int, char, double=0)
{
}
int main()
{
auto closure=
[](int x, int y)
// With or without mutable, here.
{
};
std::cout << n_lambda_parameters<decltype(closure)>::n
<< std::endl; // Prints 2.
std::cout << n_lambda_parameters<decltype(foo)>::n
<< std::endl; // Prints 3.
std::cout << n_lambda_parameters<std::function<void (int)>>::n
<< std::endl; // Prints 1.
return 0;
}
关于c++ - 基于 lambda arity 的特化函数模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56895511/
可以使用 lambda 和函数创建有序对(Lisp 中的缺点),如 Use of lambda for cons/car/cdr definition in SICP 所示。 它也适用于 Python
我正在尝试从另一个调用一个 AWS lambda 并执行 lambda 链接。这样做的理由是 AWS 不提供来自同一个 S3 存储桶的多个触发器。 我创建了一个带有 s3 触发器的 lambda。第一
根据以下源代码,常规 lambda 似乎可以与扩展 lambda 互换。 fun main(args: Array) { val numbers = listOf(1, 2, 3) f
A Tutorial Introduction to the Lambda Calculus 本文介绍乘法函数 The multiplication of two numbers x and y ca
我想弄清楚如何为下面的表达式绘制语法树。首先,这究竟是如何表现的?看样子是以1和2为参数,如果n是 0,它只会返回 m . 另外,有人可以指出解析树的开始,还是一个例子?我一直找不到一个。 最佳答案
在 C++0x 中,我想知道 lambda 函数的类型是什么。具体来说: #include type1 foo(int x){ return [x](int y)->int{return x * y
我在其中一个职位发布中看到了这个问题,它询问什么是 lambda 函数以及它与高阶函数的关系。我已经知道如何使用 lambda 函数,但不太自信地解释它,所以我做了一点谷歌搜索,发现了这个:What
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
Evaluate (((lambda(x y) (lambda (x) (* x y))) 5 6) 10) in Scheme. 我不知道实际上该怎么做! ((lambda (x y) (+ x x
我正在处理 MyCustomType 的实例集合如下: fun runAll(vararg commands: MyCustomType){ commands.forEach { it.myM
Brian 在他对问题 "Are side effects a good thing?" 的论证中的前提很有趣: computers are von-Neumann machines that are
在 Common Lisp 中,如果我希望两个函数共享状态,我将按如下方式执行 let over lambda: (let ((state 1)) (defun inc-state () (in
Evaluate (((lambda(x y) (lambda (x) (* x y))) 5 6) 10) in Scheme. 我不知道实际上该怎么做! ((lambda (x y) (+ x x
作为lambda calculus wiki说: There are several possible ways to define the natural numbers in lambda cal
我有一个数据类,我需要初始化一些 List .我需要获取 JsonArray 的值(我使用的是 Gson)。 我做了这个函数: private fun arrayToList(data: JsonAr
((lambda () )) 的方案中是否有简写 例如,代替 ((lambda () (define x 1) (display x))) 我希望能够做类似的事情 (empty-lam
我在 Java library 中有以下方法: public void setColumnComparator(final int columnIndex, final Comparator colu
我正在研究一个函数来计算国际象棋游戏中棋子的有效移动。 white-pawn-move 函数有效。当我试图将其概括为任一玩家的棋子 (pawn-move) 时,我遇到了非法函数调用。我已经在 repl
考虑这段代码(在 GCC 和 MSVC 上编译): int main() { auto foo = [](auto p){ typedef decltype(p) p_t;
我正在阅读一个在 lambda 内部使用 lambda 的片段,然后我想通过创建一个虚拟函数来测试它,该函数从文件中读取然后返回最大和最小数字。 这是我想出来的 dummy = lambda path
我是一名优秀的程序员,十分优秀!