将过载功能转换为专用功能模板
Convert overloaded functions to specialized function templates
我有一个函数,当前对不同的数据类型过载,并采用lambda(功能指针)来初始化这些数据类型。我正在将它们转换为模板实例,但尚未成功。
这是超载版本 -
#include <iostream>
using namespace std;
void doSome(int (*func)(int &)){
int a;
a = 5;
int res = func(a);
cout << a << "n";
}
void doSome(int (*func)(double &)){
double a;
a = 5.2;
int res = func(a);
cout << a << "n";
}
int main() {
doSome([](int &a){
a += 2;
return 1;
});
doSome([](double &a){
a += 2.5;
return 1;
});
return 0;
}
请注意,我以int
和double
的示例为了简化实际代码中的某些完全不同(和复杂)类型。
这是我尝试的 -
#include <iostream>
using namespace std;
template <typename F, typename S>
void doSome(F &func){
S a;
auto res = func(a);
cout << res << "n";
}
template<>
void doSome<typename F, int> (F &func){
int a;
a = 5;
auto res = func(a);
cout << res << "n";
}
template<>
void dpSome<typename F, double> (F &func){
double a;
a = 5.5
auto res = func(a);
cout << res << "n";
}
int main() {
doSome([](int &a){
a += 2;
return 1;
});
doSome([](double &a){
a += 2.5;
return 1;
});
return 0;
}
同时调用模板函数时,如果我不必将<any type hints>
传递给该功能,那将是更好的解决方案。
您的方法有一些问题。首先,您不能部分地专业化功能模板,因此从大门出发。其次,您是通过lvalue参考来掌握您的功能 - 阻止您通过lambda,这是一个prvalue。
在这种情况下,很容易在您的功能模板上添加一些Sfinae,这样一个只能与int&
调用,而仅使用double&
:
template <class F>
auto doSome(F f)
-> decltype(f(std::declval<int&>()), void())
{
// int& case
}
template <class F>
auto doSome(F f)
-> decltype(f(std::declval<double&>()), void())
{
// double& case
}
如果要制作doSome()
的通用版本,该版本不使用Sfinae进行超载分辨率,它会变得更加复杂。
#include <type_traits> // For std::remove_reference_t.
namespace detail {
// Helper to isolate return and parameter types, for a single-parameter callable.
template<typename T>
struct isolate_types;
// Function.
template<typename R, typename P>
struct isolate_types<R(P)> { using Ret = R; using Param = P; };
// Function pointer.
template<typename R, typename P>
struct isolate_types<R(*)(P)> { using Ret = R; using Param = P; }
// Pointer-to-member-function. Used for lambdas & functors.
// Assumes const this pointer.
template<typename R, typename C, typename P>
struct isolate_types<R (C::*)(P) const> { using Ret = R; using Param = P; };
// Lambda. Uses lambda's operator().
// Credit goes to ecatmur: http://stackoverflow.com/a/13359520/5386374
template<typename T>
struct isolate_types : isolate_types<decltype(&std::remove_reference_t<T>::operator())> {};
// Individual type aliases.
template<typename T>
using IsolateReturn = typename isolate_types<T>::Ret;
template<typename T>
using IsolateParam = typename isolate_types<T>::Param;
// Internal values, used by doSome().
template<typename T> T value;
template<> constexpr int value<int> = 5;
template<> constexpr double value<double> = 5.2;
// Define others as needed...
} // namespace detail
template<typename F>
void doSome(F func) {
// Determine necessary types.
using Ret = detail::IsolateReturn<F>;
using Param = std::remove_reference_t<detail::IsolateParam<F>>;
// And voila.
Param a = detail::value<Param>;
Ret res = func(a); // Can also use auto, if Ret isn't needed elsewhere.
std::cout << a << "n";
}
将其插入您的代码...
请注意,我不确定这是否适用于书面的所有lambdas,并且目前不适用于对功能的引用。但是,通过添加isolate_types
的其他专业。
相关文章:
- 在执行其他功能的同时播放动画(LED矩阵和Arduino/ESP8266)
- .cpp和.h文件中的模板专用化声明
- 多态性和功能结合
- 带内存和隔离功能的SQLite
- 调用专用模板时出错"no matching function for call to [...]"
- 模板专用化(按容器):value_type
- 在CMakeLists.txt的安装功能中使用.cmake文件有什么用
- 类模板的成员功能的定义在单独的TU中完全专业化
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- OpenMP 慢速专用功能
- C 专用模板功能接收文字字符串
- 在库中展示ConstexPR专用模板功能
- 将过载功能转换为专用功能模板
- 特定模板类型的功能专用化
- 模板专用化和普通旧功能
- 通过C 传递专用功能指针
- C++模板功能专用化
- C++具有继承功能的模板部分专用化
- C++中的专用朋友功能
- 可以是类模板内专用于类模板外的模板功能