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;icout在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);