在 c++-17 中特化的模式匹配中 lambda 的拆分函数签名
Split function signature of lambda in pattern match of specialization in c++-17
我有以下代码:
#include <iostream>
#include <string>
#include <array>
#include <map>
#include <functional>
template<typename T> struct tag {};
template <typename LambdaType, typename=void>
struct split {
split(LambdaType &&f) {
std::cout << "[]()" << std::endl;
}
};
template <typename RetType, typename... ArgTypes>
struct split<std::function<RetType(ArgTypes...)>> {
split(std::function<RetType(ArgTypes...)> &&f) {
std::cout << "std::function" << std::endl;
};
};
template <typename RetType, typename... ArgTypes>
struct split<RetType(*)(ArgTypes...)> {
split(RetType(*f)(ArgTypes...)) {
std::cout << "func-ptr" << std::endl;
};
};
void f1(int) {};
int
main(int argc, char **argv) {
new split<std::decay<decltype(f1)>::type>(f1);
new split<std::function<void(int)>>(std::function<void(int)>([](int) {}));
/* how can I extract the argument type template pack from lambda ? */
new split([](int){});
return 0;
}
split
有2个专业,一个std::function<RetType(ArgTypes...)>
专业,一个RetType(*)(ArgTypes...)
专业。对于这两种专业化,我都得到了RetType
和ArgTypes...
模板参数,并通过模式匹配打包。但是我想知道天气有没有办法用lambda
作为论据来做同样的事情?
如何在new split([](int){})
系的专用化中提取 lambda 的RetType
和ArgTypes...
?
您可以将模板类参数推导与std::function
一起使用:
template <typename LambdaType, typename=void>
struct split {
using StdFunctionType = decltype(std::function{std::declval<LambdaType>()});
};
获得与 lambda 对应的std::function
后,您可以使用模板专用化检索返回和参数类型。
这是有效的std::function
因为有一个扣除指南:
template<class F>
function(F) -> function</*see below*/>;
如果
decltype(&F::operator())
对于某些类类型G
具有R(G::*)(A...)
形式(可选cv
限定,可选noexcept
,可选右值引用限定),则推导类型为std::function<R(A...)>
。仅当&F::operator()
在被视为未计算的操作数时格式正确时,此重载才会参与重载解析。
你可以经历一些诡计,例如:
#include <type_traits>
template <typename LambdaType, typename=void>
struct split {
split(LambdaType &&f) { deduce(&LambdaType::operator()); }
template<class RET, class CLOSURE, class... ARGS>
void deduce(RET(CLOSURE::*)(ARGS...) const) {
// You have your return and args here
}
};
template <typename RetType, typename... ArgTypes>
struct split<RetType(*)(ArgTypes...)> {
split(RetType(*f)(ArgTypes...));
};
void f1(int) {};
int
main(int argc, char **argv) {
split<std::decay_t<decltype(f1)>>{f1};
/* how can I extract the argument type template pack from lambda ? */
split([](int){});
return 0;
}
我找到了一种使用子类化特化的方法(见这里):
/* g++ -std=c++17 */
#include <iostream>
#include <string>
#include <array>
#include <map>
#include <functional>
template<typename T> struct tag {};
struct mybase {};
/* subclass specialization on type of operator() of lambda: */
template<class Ld>
struct split : split<decltype(&Ld::operator())>
{
split(Ld &&f) : split<decltype(&Ld::operator())>(std::forward<Ld>(f)) {};
};
template <typename RetType, typename... ArgTypes>
struct split<std::function<RetType(ArgTypes...)>> {
split(std::function<RetType(ArgTypes...)> &&f) {
std::cout << "std::function" << std::endl;
};
};
template <typename RetType, typename... ArgTypes>
struct split<RetType(*)(ArgTypes...)> {
split(RetType(*f)(ArgTypes...)) {
std::cout << "func-ptr" << std::endl;
};
};
template <typename RetType, class Cls, typename... ArgTypes>
struct split<RetType(Cls::*)(ArgTypes...) const > {
split(const Cls &&f) {
std::cout << "[]() const" << std::endl;
};
};
template <typename RetType, class Cls, typename... ArgTypes>
struct split<RetType(Cls::*)(ArgTypes...) > {
split(Cls &&f) {
std::cout << "[]()" << std::endl;
};
};
void f1(int) {};
int
main(int argc, char **argv) {
new split<std::decay<decltype(f1)>::type>(f1);
new split<std::function<void(int)>>(std::function<void(int)>([](int) {}));
/* no g++-17: */
//auto l = [](int){};
//new split<decltype(l)>(std::forward<decltype(l)>(l));
/* g++-17: */
new split([](int){});
return 0;
}
相关文章:
- C++(.cpp文件和.h文件)拆分代码并添加一个函数,提取 - 这很容易吗?
- 为什么最后一个拆分函数会导致分割故障?如何解决此问题
- Doxygen,当参数类型定义使签名相同时,如何拆分函数文档?
- 根据函数指针参数拆分多个可变参数模板包
- 在 c++-17 中特化的模式匹配中 lambda 的拆分函数签名
- 拆分函数的声明和定义,还是删除标头中的新运算符?
- C++ 提升:拆分函数 is_any_of()
- 拆分函数 c++
- 使用 string::find 和 string::substr 拆分字符串的函数返回错误的标记
- 将字符串拆分为令牌-不包含操作系统特定的函数
- C++字符串拆分函数Eclipse中出现错误,但已编译
- 如何在 c++ 中将此公式拆分为函数
- 有一个入门 C++ 类的编程项目 我们需要创建的函数之一是拆分函数
- C++ 中的模板拆分类构造函数的迭代器类型
- C++ strtok 函数拆分单词
- 在类构造函数中拆分字符串
- 如何在不使用任何基本函数的情况下拆分字符数组
- 无法拆分头文件和源文件中具有静态成员函数的类
- 取消对拆分函数调用参数的信任
- 拆分函数引发错误