传递函子或函数作为参数

Passing a functor or a function as an argument

本文关键字:参数 函数      更新时间:2023-10-16

我对c++有点陌生,我目前正在摆弄模板以更好地理解它们。以下是我一直在尝试的:

#include <iostream>
#include <typeinfo>
using namespace std;
template <typename T>
class someContainer
{
private:
    T val1;
    T val2;
public:
    someContainer(const T& in1, const T& in2)
        :val1(in1), val2(in2) {}
    template <template <typename Ty> class Comp>
    void sort()
    {
        bool result = Comp<T>()(val1, val2);
        cout << result << endl;
        return;
    }
};
template <typename R>
class Compare
{
public:
    bool operator () (const R& a, const R& b)
    {
        return a>b;
    }
};

int main()
{
    someContainer<int> myCont(7,6);
    myCont.sort<Compare>();

    cin.ignore();
    return 0;
}

我想做几乎相同的事情,但这次是一个函数。基本上是这样的:

myCont.sort<function>();

只是为了确定-我不想要这个:

#include <iostream>
#include <typeinfo>
using namespace std;
template <typename T>
class someContainer
{
private:
    T val1;
    T val2;
public:
    someContainer(const T& in1, const T& in2)
        :val1(in1), val2(in2) {}
    template <class Func>
    void sort(Func func)
    {
        bool result = func(val1,val2);
        cout << result << endl;
        return;
    }
};
//Try for sort functor
template <typename R>
bool compare(const R& a, const R& b)
{
    return a>b;
}

int main()
{
    someContainer<int> myCont(7,6);
    myCont.sort(compare<int>);

    cin.ignore();
    return 0;
}

/编辑:我意识到我可能没说清楚。我想把它叫做myCont.sort<function>,这可能吗?我意识到函数不是你所说的类但是可以传递一个泛型函数给sort():

#include <iostream>
#include <typeinfo>
using namespace std;
template <typename T>
class someContainer
{
private:
    T val1;
    T val2;
public:
    someContainer(const T& in1, const T& in2)
        :val1(in1), val2(in2) {}
    template <typename Ty>
    void sort(bool (*_comp)(const Ty&, const Ty&))
    {
        cout << "Comp is of type: " << typeid(_comp).name() << endl;
        cout << _comp(val1, val2) << endl;
        return;
    }
};
template <typename R>
bool compare(const R& a, const R& b)
{
    return a>b;
}
int main()
{
    someContainer<int> myCont(7,6);
    myCont.sort(compare<int>); 

    cin.ignore();
    return 0;
}

我甚至可以定制它的返回类型:

#include <iostream>
#include <typeinfo>
using namespace std;
template <typename T>
class someContainer
{
private:
    T val1;
    T val2;
public:
    someContainer(const T& in1, const T& in2)
        :val1(in1), val2(in2) {}
    template <typename Ret, typename Ty>
    void sort(Ret (*_comp)(const Ty&, const Ty&))
    {
        cout << "Comp is of type: " << typeid(_comp).name() << endl;
        cout << _comp(val1, val2) << endl;
        return;
    }
};
template <typename Ret, typename R>
Ret compare(const R& a, const R& b)
{
    return a>b;
}
int main()
{
    someContainer<int> myCont(7,6);
    myCont.sort(compare<bool,int>); 

    cin.ignore();
    return 0;
}

但这不是问题。我知道我没有以最好的方式解释它,所以如果你想让我补充什么,请告诉我。我的想法是,我希望能够做这样的事情:myCont.sort ();或

myCont.sort(函数);

问题要点:是否有一种方法可以将函数模板作为参数传递给另一个函数的模板-就像我将类模板作为参数传递给另一个函数的模板一样:

myCont.sort<Compare>(); // Compare is a template - not a template specialization
//later in sort we got Comp<T>()()

如果我有一个名为compare的函数模板,是否有办法做以下任何事情:

myCont.sort<compare>();
myCont.sort(compare);

我想传递一个函数模板——而不是比较的特化——我可以用函子来实现,所以我想知道是否可以用函数来实现。我不希望有:

myCont.sort(compare<some_type>);

我想取一个函数模板,然后在sort()中获得它的专门化。

提前感谢!

注。似乎评论只能是小尺寸的,所以这里有另一个问题:你认为这(myCont.sort(compare))是可能的(如果在c++中函数模板参数有默认值)与这段代码吗?

#include <iostream>
#include <typeinfo>
using namespace std;
template <typename T>
class someContainer
{
private:
    T val1;
    T val2;
public:
    someContainer(const T& in1, const T& in2)
        :val1(in1), val2(in2) {}
    template <typename Ret = bool ,typename Ty = T>
    void sort(Ret (*_comp)(const T&, const T&))
    {
        cout << "Comp is of type: " << typeid(_comp).name() << endl;
        cout << _comp(val1, val2) << endl;
        return;
    }
};
template <typename Ret, typename R>
Ret compare(const R& a, const R& b)
{
    return a>b;
}
int main()
{
    someContainer<int> myCont(7,6);
    myCont.sort(compare); 
    cin.ignore();
    return 0;
}

公立小学

顺便说一句,一切都始于我想知道为什么我不能编译这个(显然是因为缺少一些func,但这是合乎逻辑的列表。sort应该能够从列表专门化的类型中推断出someFunc的类型):

#include <iostream>
#include <list>
using namespace std;
template <typename T>
void display(const T& input)
{
    for(auto i = input.cbegin(); i!=input.cend(); ++i)
        cout << *i << ' ';
    cout << endl;
    return;
}
template <typename R>
bool someFunc(const R& in1, const R& in2)
{
    return in1>in2;
}
int main()
{
    list<int> myList;
    myList.push_back(5);
    myList.push_back(137);
    myList.push_back(-77);
    display(myList);
    myList.sort(someFunc); //change it to myList.sort(someFunc<int>) and it works
    //however I believe the compiler should be able to infer the type of someFunc from
    //the type of myList - I guess the STL just wasn't written for having template 
    //functions as a binary predicate
    display(myList);
    cin.ignore();
    return 0;
};

c++没有任何表示一组重载函数或函数模板的类型。传递一组函数的唯一方法是作为包含它们的类。

如果想传递单个函数(可能是模板函数实例),可以使用函数指针(甚至可能是引用)作为模板实参。但是函数的类型不能推断,它必须与模板实参的形式类型完全匹配。作为模板实参而不是普通形参传递它几乎没有什么价值——如果形参是常量,那么在内联过程中,一个好的编译器会优化函数指针指向直接调用,甚至内联它。


对编辑的回应:

myCont.sort(compare) 工作。您只是在代码中犯了一个小错误,创建了一个模板参数Ty而从未使用它。未使用的参数不能被推导出来。看

  • http://ideone.com/NMalai

顺便说一下,不是这个

template <typename R>
class Compare
{
public:
    bool operator () (const R& a, const R& b)
    {
        return a>b;
    }
};

你可能喜欢

class Compare
{
public:
    template <typename R>
    bool operator () (const R& a, const R& b)
    {
        return a>b;
    }
};

和新的c++ 14 lambdas可以自动生成模板化的operator()