【问题标题】:Is it possible to place function pointer in template parameter ahead of dependent type?是否可以将函数指针放在依赖类型之前的模板参数中?
【发布时间】:2015-08-10 22:56:21
【问题描述】:

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

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

【问题讨论】:

  • @PiotrSkotnicki:谢谢。不幸的是,这就是我一直在寻找的答案。 IE。到目前为止还不能完成。 :-(
  • 有几个问题:get_param_t 需要函数指针,但您在 param_t 的定义中提供了函数类型。而不是decltype(get_param_type&lt;Ret(P)&gt;()),只需使用PWrapper 需要函数类型,但您为其提供函数指针。使用Wrapper&lt;decltype(F)&gt;Wrapper&lt;F&gt;::function 是一个模板,你需要指定它的参数:Wrapper&lt;decltype(F)&gt;::function&lt;F&gt;。最重要的是,不可能以您想要的方式声明make_wrapper。这就是我使用宏而不是模板方法的原因。

标签: templates c++11


【解决方案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>

【讨论】:

  • 嗯,也许是早上太早了,但我不明白。能否举个例子说明一下它的用法?
  • @Adrian 要使用它,只需使用宏:FUNCTION(theFunctionYouWantToPassToTemplate)。它将返回适当的function 实例,其中包含可用于otherType 的填充模板参数(RetParams...fn)。在此示例中,它返回一个可用于调用 fn (FUNCTION(theFunction)(param1, param2, param3)) 的函数,因此它没有多大用处,但您可以轻松地将其更改为返回其他内容。
  • 抱歉,我还是没听懂。我更新了我的问题,希望您能理解我想要完成的工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-17
  • 2016-08-23
  • 2014-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多