是否可以将函数指针放在模板参数之前的依赖类型?

时间:2015-08-10 22:56:21

标签: templates c++11

我有一个模板,它有一个函数指针作为它的第二个参数和一个函数指针依赖的类型。

template <typename P, typename void(*fn)(P)>
auto function(P) -> otherType<P, fn>;

我想这样做,以便我可以在模板列表中指定函数指针而不必指定依赖类型,因为应该以某种方式能够从函数指针中推断出我指定(或也许甚至参数列表,但我认为它可能太过分了。)

我的第一个想法是通过传递模板类型名称将转换推迟到模板参数值,然后通过模板元编程魔法转换为事后的值。

template <typename F, typename P>
auto function(P) -> [[ something here to get otherType<P, fn> if F was a function pointer ]]

但是,我不确定如何才能做到这一点。有什么想法吗?

修改

我在这里尝试完成的是创建一个生成类对象的辅助函数。所以,考虑到StenSoft的说法,这就是我提出的。不幸的是,它不适用于main()函数内部的失败,因为扣除失败导致它无法与正确的函数匹配:

#include <iostream>
#include <functional>

template<typename T, typename F>
struct wrapper_fntor
{
  T m_t;
  F m_f;
  wrapper_fntor(T t, F f) : m_t(t), m_f(f) {}
  void invoke() { m_f(m_t); }
};

template<typename T, void(*fn)(T)>
struct wrapper_fn
{
  T m_t;
  wrapper_fn(T t) : m_t(t) {}
  void invoke() { fn(m_t); }
};

template <typename T>
struct Wrapper;

template <typename Ret, typename P>
struct Wrapper<Ret(P)>
{
    template <Ret(*fn)(P)>
    static Ret function(P p)
    {
        return fn(std::forward<P>(p));
    }
    template <Ret(*fn)(P)>
    static P get_param_type(P);

    typedef decltype(get_param_type<Ret(P)>()) param_t;
};

template<typename F>
wrapper_fn<typename Wrapper<F>::param_t, &Wrapper<F>::function> make_wrapper(typename Wrapper<F>::param_t param)
{
  return wrapper_fn<typename Wrapper<F>::param_t, &Wrapper<F>::function>(param);
}

template<typename F>
wrapper_fntor<typename Wrapper<F>::param_t, F> make_wrapper(typename Wrapper<F>::param_t param, F fntor)
{
  return wrapper_fntor<typename Wrapper<F>::param_t, F>(param, fntor);
}


void function(int value)
{
    std::cout << "function called " << value << std::endl;
}

int main()
{
    auto x = make_wrapper<function>(3);
    x.invoke();
}

demo

1 个答案:

答案 0 :(得分:1)

对于类似的问题,我在模板化的包装类和宏中使用了模板化函数(这实际上适用于任何参数和返回类型):

template <typename T>
struct Wrapper;

template <typename Ret, typename... Params>
struct Wrapper<Ret(Params...)>
{
    template <Ret(*fn)(Params...)>
    static Ret function(Params... params)
    {
        return fn(std::forward<Params>(params)...);
    }
};

#define FUNCTION(fn) \
    Wrapper<decltype(fn)>::function<fn>