c++ - 将函数作为参数传递给模板函数问题

标签 c++

我正在尝试创建一个具有 5 个参数的模板函数,其中四个应该是迭代器,第五个应该是一个函数。函数应该做什么它应该基本上转换作为参数传递的第一个和第二个迭代器之间的 block 中的每个元素,并将它们复制在作为参数传递的第三个和第四个迭代器之间,使用第五个参数(函数)来转换元素。返回值是第一个 block 的所有元素的总和。

这是我想出来的

#include <iostream>
#include <type_traits>
#include <vector>
#include <deque>
using namespace std;

int funk(int a) {
    return a*=2;
}

template <typename IterType1, typename IterType2>
auto MyFunction(IterType1 p1,
                IterType1 p2,
                IterType2 p3,
                IterType2 p4,
                decltype(p1[0]) CriteriaFunction(decltype(p1[0])))
-> decltype(p1[0])
{

    auto temp= remove_reference<decltype (p1[0])>::type;
    while(p1 != p2) {
        temp+=*p1;

        *p3++ = CriteriaFunction(*p1);
        p1++;

    }
    p4=++p3;

    return temp;
}

int main()
{
    vector<int> v1 = {1,2,3,4,5};
    deque<double> d1(5);

    auto it1 = v1.begin();
    auto it2 = v1.end();
    auto it3 = d1.begin();
    auto it4 = d1.end();

    cout << MyFunction(it1, it2, it3, it4, funk);
    return 0;

现在,我不确定我的模板函数是否会按照我编写的方式实际工作,但我稍后会对其进行更改。问题是这甚至无法编译,错误是:

main.cpp|48|error: invalid user-defined conversion from 'main()::<lambda(int)>' to 'int& (*)(int&)' [-fpermissive]|

现在,我熟悉将函数作为参数传递给其他函数,但是如果模板接收的函数取决于模板的类型名参数,该怎么办。我的语法错了吗?我该如何解决这个问题?

最佳答案

你的语法没有错,但是decltype(p1[0])int & , 不是 int , 所以你的函数有错误的类型。

MyFunction实际上想要一个 int &(*)(int &) ,但是 funk类型为 int (*)(int) (它接受并返回一个普通的 int ,而不是一个引用)。

你可以使用 remove_reference , 但解决此问题的最简单方法是不要费心去描述确切的类型。这样做无论如何都会不必要地限制你:它会阻止 lambda 和带有 operator() 的对象。从被使用。

为什么不这样做:

template <typename IterType1, typename IterType2, typename FuncType>
auto MyFunction(IterType1 p1, IterType1 p2, IterType2 p3, IterType2 p4, FuncType CriteriaFunction) {
    ...
}

?让编译器操心 FuncType 的细节.

下面两个问题:

auto temp= remove_reference<decltype (p1[0])>::type;

编译器假定(就像它总是对从属名称所做的那样)remove_reference<decltype (p1[0])>::type指的是一个值,而不是一个类型。这也是进行初始化所需的 auto temp = ...编译。但是如果你试图实例化这个函数模板,它将失败,因为 ::type是一种类型,而不是一个值。

您可以使用 typename告诉编译器 ::type实际上是一种类型:

auto temp = typename remove_reference<decltype (p1[0])>::type;

...但这是一个语法错误,就像 auto i = int;会是。

但是,

auto temp = typename remove_reference<decltype (p1[0])>::type();

编译和工作。这里我们实例化一个 remove_reference<...>::type 类型的默认值。 .

关于c++ - 将函数作为参数传递给模板函数问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56813391/

相关文章:

c++ - 使用带有 QModelIndexes 列表的 concurrent::map()

c++ - c++中友元声明的内容错误基础

c++ - OpenGL:在代码中生成椭圆

c++ - 为什么编译器提示 std::thread 参数在转换为右值后必须是可调用的?

c++ - 如何从终端运行用 eclipse 编写的 c++ 程序

c++ - 编译器在错误时显示 'pi' 符号

c++ - QQuickPaintedItem 中集成 QWidget 时 setVisible 返回 false

c++ - sin(<minus zero>) 未在 Visual Studio 2013 64 位上返回预期结果

c++ - 包含 C++ 源文件中的 Obj-C++ header

c++ - 为什么在使用之前需要转换通用引用的参数?