如何使用 std::function 指向函数模板

发布于 2024-10-20 06:12:43 字数 447 浏览 4 评论 0原文

#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;
}

但是可以指向模板函数吗?

#include <functional>

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

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

    return 0;
}
#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()
{
    typedef std::function<?(?, ?)> Funcp;
    Funcp funcp = func;

    return 0;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

笛声青案梦长安 2024-10-27 06:12:43

C++ 中不存在模板函数这样的东西——人们随意提到的“模板函数”实际上是函数模板:定义函数的模板。

因此,上面第二个示例中的 func 不是一个函数,它是一个(函数)模板,并且它不能像函数一样使用。特别是,std::function 希望提供一个函数。

如何解决这个问题取决于您想要实现的目标。如果您尝试使使用该函数的代码适用于任何类型,您只需将该代码放置在函数或类模板中:

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

但是,您将无法做的是使用通用类型量词的后期绑定(“可以应用于任何类型”),因为“可以应用于任何类型”在 C++ 中必然在编译时解析。事情就是这样滚动的。

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.

心头的小情儿 2024-10-27 06:12:43

不,模板函数就是模板。这不是一个真正的函数。您可以将 std::function 指向模板函数的特定实例,例如 func

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>

混浊又暗下来 2024-10-27 06:12:43

这是你想要的吗?

#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>;
}

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>;
}
绅刃 2024-10-27 06:12:43

正如埃里克指出的那样,这不可能直接实现。为了达到您可能想要的效果,您必须将使用指针的代码制作为模板。

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.

短暂陪伴 2024-10-27 06:12:43

这个解决方案可能有点棘手。

假设您想使用指定的键(对类型)调用函数,
您可以通过以下两种方式索引 func ptr:

#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;
}

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文