开发者

how to use std::function to point to a function template

开发者 https://www.devze.com 2023-02-14 06:07 出处:网络
#include <functional> int func(int x, int y) { return x + y; } int main() { typedef std::function<int(int, int)> Funcp;
#include <functional>

int func(int x, int y)
{
    return x + y;
}

int main()
{
    typedef std::function<int(int, int)> Funcp;
    Funcp funcp = func;

    return 0;
}

But is it possible to point to a template function?

#include <functional>

template<class T>
T func(T x, T y)
{
    return x + y;
}

int main()
{
    typ开发者_如何学JAVAedef std::function<?(?, ?)> Funcp;
    Funcp funcp = func;

    return 0;
}


There is no such thing as a template function in C++ — what people casually mention as "template functions" are actually function templates : templates which define functions.

As such, func in your second example above is not a function, it's a (function) template, and it cannot be used in the same way as a function can. In particular, std::function expects to be provided with a function.

How you can work around this depends on what you are trying to achieve. If you're trying to make the code that uses the function work with any type, you can simply place that code in a function or class template:

template <typename T>
void use_function(T t) {
  typedef std::function<T(T,T)> Funcp = func<T>;
  // use Funcp here
}

What you will not be able to do, however, is use late binding with universal type quantifiers ("can be applied to any type"), because "can be applied to any type" is necessarily resolved at compile-time in C++. That's just how it rolls.


No. A template function is exactly that, a template. It's not a real function. You can point a std::function to a specific instantiation of the template function, e.g. func<int,int>


Is this what you want?

#include <functional>

template<class T>
T func(T x, T y)
{
    return x + y;
}

template<typename T> struct FunctionType
{
    typedef std::function<T(T, T)> Type;
};

int main()
{
    FunctionType<int>::Type Funcp = func<int>;
}


As Erik points out, this is not possible directly. To achieve the effect you probably desire, you would have to make the code that uses the pointer a template.


this resolution may be a little tricky.

supposed you want calling function with a specified key(pair type), you may indexing the func ptr in following 2 ways:

#include <iostream>
#include <unordered_map>
#include <map>
#include <functional>
#include <vector>

using namespace std;

enum A {
    RGB=3, YUV=2, GRAY=4
};

template<A t, A tt>
void f() {
    cout << "default" << endl;
    cout << t << endl;
    cout << tt << endl;
}

template<>
void f<A::RGB, A::YUV>() {
    cout << "spec rgb -> yuv" << endl;
}

template<>
void f<A::YUV, A::RGB>() {
    cout << "spec yuv -> rgb" << endl;
}

template<>
void f<A::YUV, A::GRAY>() {
    cout << "spec yuv -> gray" << endl;
}


int main()
{
    f<YUV,RGB>(); // yuv -> rgb
    std::vector<std::pair<std::pair<A,A>, std::function<void()>> > vec;
    vec.push_back(make_pair(make_pair(A::RGB, A::YUV), f<A::RGB,A::YUV>));
    vec.push_back(make_pair(make_pair(A::YUV, A::GRAY), f<A::YUV,A::GRAY>));
    vec.push_back(make_pair(make_pair(A::YUV, A::RGB), f<A::YUV,A::RGB>));
    auto functor = vec[0].second;
    functor(); // rgb->yuv
    
    for (auto iter = vec.begin(); iter != vec.end(); iter++) {
        if (iter->first == make_pair(A::YUV,A::GRAY)) {
            (iter->second)(); // yuv -> gray
            break;
        }
    }
    
      std::map<std::pair<A,A>, void(*)()> mmap;
    mmap.emplace(make_pair(RGB, YUV), f<RGB,YUV>);
    mmap.emplace(make_pair(YUV, GRAY), f<YUV,GRAY>);
    
    mmap[make_pair(YUV,GRAY)]();
    return 0;
}
0

精彩评论

暂无评论...
验证码 换一张
取 消