【问题标题】:Split multiple variadic template packs based on function pointer arguments根据函数指针参数拆分多个可变参数模板包
【发布时间】:2017-02-09 04:35:02
【问题描述】:

我正在尝试创建一些基于模板的函数来打包函数指针和一些输入参数,然后调用它并将一些输出值存储在其他地方。首先,我尝试创建一个函数,其中一个可变参数模板用于输入参数,一个用于返回值。这是我想出的,但它不起作用:

template<typename... Args, typename... Ret>
void Call(void (*func)(Args..., Ret...), Args&&... args)
{

}

void Foo(float x, int& y)
{
    y = int(x * x);
}

int main(int argc, const char* argv[])
{
    Call(&Foo, 2.f);
    return 1;
}

ideon 给我以下错误:

prog.cpp: In function 'int main(int, const char**)':
prog.cpp:16:16: error: invalid conversion from 'void (*)(float, int&)' to 'void (*)(float, float, int&)' [-fpermissive]
  Call(&Foo, 2.f);
                ^
prog.cpp:4:6: note:   initializing argument 1 of 'void Call(void (*)(Args ..., Ret ...), Args&& ...) [with Args = {float}; Ret = {float, int&}]'
 void Call(void (*func)(Args..., Ret...), Args&&... args)
      ^

为什么Ret 会被推导出为{float, int&amp;}?推导中明明用了函数指针参数,但好像没有用到Args...

【问题讨论】:

  • 您希望Ret 是什么?是返回值吗?
  • 在这个例子中,我希望Ret{int&amp;}Args{float}Args 因为 CallRet 的尾随参数,因为这是函数指针参数中剩下的内容。但也许这好得令人难以置信?
  • std::tuple&lt;Ret...&gt; (*func)(Args...) 会更容易使用..
  • @Jarod42 是的,但我更喜欢输入参数后跟返回参数,以保持与其余代码的一致性。
  • 我强烈建议改为返回std::tuple

标签: c++ templates variadic-templates variadic-functions


【解决方案1】:

您可以添加一个图层来修复一些模板参数:

template <typename ... Ts>
struct helper
{
    template <typename ...Ret, typename ... Us>
    static void Call(void (*func)(Ts..., Ret...), Us&&... args)
    {

    }

};


template<typename F, typename... Args>
void Call(F&& f, Args&&... args)
{
    helper<Args...>::Call(std::forward<F>(f), std::forward<Args>(args)...);
}

Demo

【讨论】:

    猜你喜欢
    • 2011-07-25
    • 2022-01-05
    • 2013-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-29
    • 2013-12-26
    • 1970-01-01
    相关资源
    最近更新 更多