C++ 模板化函数模板参数的返回类型
我正在尝试编写一些样板,用于在传递到各种签名函数之前转换参数类型。最简单的示例是获取一个需要C++ 模板化函数模板参数的返回类型,c++,c++14,C++,C++14,我正在尝试编写一些样板,用于在传递到各种签名函数之前转换参数类型。最简单的示例是获取一个需要int*的函数,并将其包装以创建一个采用std::vector的函数,如下例所示 #include <vector> #include <iostream> using namespace std; template <void (*F)(int*, size_t)> void tfunc_api(vector<int>& a) { retu
int*
的函数,并将其包装以创建一个采用std::vector
的函数,如下例所示
#include <vector>
#include <iostream>
using namespace std;
template <void (*F)(int*, size_t)>
void tfunc_api(vector<int>& a)
{
return F(&(a[0]), a.size());
}
void reset(int* a, size_t n)
{
for (size_t i=0; i < n; i++)
{
a[i] = 0;
}
}
int main(void)
{
vector<int> foo = {1,2,3,4};
tfunc_api<reset>(foo);
for (auto e: foo)
cout << e << endl;
}
然后我可以为模板参数int(*F)(int*,size\u t)
编写一个新的专门化tfunc\u api
但是,只对返回类型进行模板化会更方便。我所有引入额外模板参数的尝试都失败了。这可能吗?如果可能,如何实现?或者有更好的方法吗?在C++17中,一个超级简单的解决方案是
auto
:
template <auto (*F)(int*, size_t)>
auto tfunc_api(vector<int>& a)
模板
自动tfunc_api(矢量和a)
或者更通用:
template <auto F>
auto tfunc_api(vector<int>& a)
模板
自动tfunc_api(矢量和a)
更通用的方法对于不局限于函数指针非常有用,并且可以与其他可调用项一起使用,例如捕获lambda。如果使用错误的签名调用,则错误消息可能不太明显
在C++14中,我会将callable作为常规参数传递,而不是模板参数:
template <class Fun>
auto tfunc_api(vector<int>& a, Fun F)
// call
tfunc_api(foo, sum);
模板
自动tfunc_api(向量&a、函数)
//召唤
tfunc_api(foo,sum);
您可以使用lambda而不是模板化函数在C++14中执行此操作,无需详细说明:
auto tfunc_api = [] (auto F, vector<int>& a)
{
return F(&(a[0]), a.size());
};
void reset(int* a, size_t n)
{
for (size_t i=0; i < n; i++)
{
a[i] = 0;
}
}
int sum(int* a, size_t n)
{
int sum = 0;
for (size_t i=0; i < n; i++)
{
sum += a[i];
}
return sum;
}
int main(void)
{
vector<int> foo = {1,2,3,4};
cout << tfunc_api(sum, foo) << endl;
tfunc_api(reset, foo);
for (auto e: foo)
cout << e << endl;
}
auto-tfunc\u-api=[](auto-F,vector&a)
{
返回F(&(a[0]),a.size();
};
无效重置(整数*a,大小\u t n)
{
对于(大小i=0;i cout在C++14中保持F
作为模板参数的唯一方法似乎是引入类型模板参数,然后使用decltype
:
template<class T, T F>
auto tfunc_api(std::vector<int>& a)
{
return F(&a[0], a.size());
}
std::cout << tfunc_api<decltype(sum), sum>(foo);
模板
自动tfunc_api(标准::向量&a)
{
返回F(&a[0],a.size());
}
std::我现在只能使用c++14
,但我可以使用冗长。哦,这很酷,其他参数决定了乐趣的签名。非常感谢。出于好奇:有没有办法保留(*F)(…)
作为C++14中的模板参数,并执行OP想要的操作?将callable作为常规参数传递的一个缺点是,您不能再获取特定tfunc_api
的地址。这个问题的原始上下文需要这样做,所以像@Evg一样,我也很好奇。@ChrisD不应该&tfunc_api
工作吗?
template<class T, T F>
auto tfunc_api(std::vector<int>& a)
{
return F(&a[0], a.size());
}
std::cout << tfunc_api<decltype(sum), sum>(foo);