推断可调用对象的第一个参数
Infer the first argument of a callable
我希望能够推断可调用对象的第一个参数。我可以让它为免费和成员函数工作,但我正在与lambda作斗争。有什么我可以用的技巧吗?
这里有一个例子。在下面的match
函数中,我想使用T
的知识。
template<class T>
void match(void (*)(T*, int)) { /* First */ }
template<class T>
void match(void (T::*)(int)) { /* Second */ }
template<class T>
void match(std::function<void(T,int)>) { /* Third */ }
struct A
{
void f(int) {}
};
void g(A*, int) {}
match(&A::f); // Ok, matches first
match(&g); // Ok, matches second
match([](A*, int) {}); // Not Ok
match([&](A*, int) {}); // Not Ok
你不能。
template<class T>
void g(T*, int) {}
无法工作
void g(void*, int) {}
void g(std::string**, int) {}
无法工作。
同样的问题也存在于lambdas中。
作为一般规则,您可以询问"can I invoke X with type Y",但您无法获得签名。
std::function
不是λ, λ也不是std::function
。它们是不相关的类型,除了您可以将lambda转换为具有任何兼容签名的std::function
,就像您可以转换任何可调用对象一样。
如果你的问题空间足够有限,你可以写一个trait类来提取传入对象的operator()
签名,并将其作为lambda的参数。
这在c++ 11中是一个坏主意,在c++ 14和c++ 17中通常会变得更糟。[](auto a, int b){}
是c++ 14中的lambda(许多c++ 11编译器都支持它),它的第一个参数没有固定的类型。
auto&&
参数。
另一种方法是问"这些类型中哪一个有效",这是可以做到的。通常,您所使用的类型并不是无限的,而是一个枚举集。
我知道只有一个办法:通过std::function
match(std::function<void(A*, int)>([](A*, int) {}));
match(static_cast<std::function<void(A*, int)>>([&](A*, int) {}));
相关文章:
- C++部分概念 id:显式模板规范顺序/第一个参数的特殊状态的原因是什么?
- 可变参数模板作为第一个参数
- 如何从第一个参数推断第二个参数类型?
- 候选构造函数(隐式复制构造函数)不可行:第一个参数需要 l 值
- 为什么 std::error_code 构造函数的第一个参数固定为 int
- 如何通过 std::apply 调用具有定义的第一个参数的可变参数模板函数?
- 如何获取指向 qsort 第一个参数的向量中第一项的指针?
- 如何在 Lua 回调中检测可选的第一个参数
- 如何让我的 strchr 函数同时将'const char'数组和'char'数组作为第一个参数?
- 在第一个参数上部分专用化模板
- 模板的C 功能将第一个参数设置为第二个参数为默认参数
- 如何获取指向函数第一个参数的指针
- 我可以使用use_lazy_terminal对获得3个参数懒惰的终端的第一个参数
- C++比较运算符重载中第一个参数为 null 时出现分段错误
- Cc 套接字编程 select() 的第一个参数
- 重载运算符:第一个参数对应左操作数,第二个参数对应右操作数
- 仅初始化c++11元组的第一个参数
- 我可以使用成员函数作为EnumWindows的第一个参数吗
- gdb只接受第一个参数
- 等键在 boost::unordered_multimap 中起作用:查询键是否保证是第一个参数