如何将推导的函数指针类型传递给函数指针模板参数

时间:2013-11-13 19:29:43

标签: c++ templates

有没有办法从构造函数Caller<pfn>中实例化Foo()

#include <iostream>
using namespace std;

struct Foo
{
    template<void(*pfn)()>
    struct Caller
    {
        static void call() { pfn(); }
    };

    template<typename FN>
    Foo(FN fn)
    {
        Caller<FN>::call();  // illegal type for non-type template parameter 'pfn'
    }
};

void Bar()
{
    cout << "bar" << endl;
}

int main(int argc, char *argv[])
{
    Foo foo(&Bar);
    return 0;
}

3 个答案:

答案 0 :(得分:1)

您需要为类提供函数的类型,而不仅仅是构造函数。这只是一种解决方法,您可以将其作为起点:

template <typename F>
struct Foo
{
    struct Caller
    {
        static void call(F fn)
        {
            fn();
        }
    };

    Foo(F fn)
    {
        Caller::call(fn);
    }
};

void Bar()
{
    cout << "bar" << endl;
}

int main()
{
    Foo<decltype(Bar)> foo(Bar);
}

如果Foo不能作为模板库,那么请使用:

struct Foo
{
    template <typename F>
    struct Caller
    {
        static void call(F fn)
        {
            fn();
        }
    };

    template <typename F>
    Foo(F fn)
    {
        Caller<F>::call(fn);
    }
};

void Bar()
{
    cout << "bar" << endl;
}

int main()
{
    Foo foo(Bar);
}

答案 1 :(得分:0)

也许你的意思就像他跟随的那样:

#include <iostream>

using namespace std;

struct Foo
{
    template<void(*pfn)()> // CHANGED
    struct Caller
    {
        static void call() { pfn(); }
    };
};

void Bar()
{
    cout << "bar" << endl;
}

int main(int argc, char *argv[])
{
    Foo::Caller<&Bar>::call(); // CHANGED
}

请注意这里的变化:

 template<void(*pfn)()>

答案 2 :(得分:0)

这是不可能的。

编译时常量函数指针在作为函数参数传递后不能用作一个。

此外,仅使用函数指针类型无法获取特定函数的编译时常量函数指针。