为什么variadic模板参数的替换失败?(在固定参数之前打包)

Ad *_*d N 5 c++ templates variadic-templates c++11

这是触发编译错误的最小示例:

#include <utility>
void foo(int, double, int)
{}

template <class... Args>
void post_forwarder(void(*fun)(Args..., int), Args&&... aArgs)
{
    fun(std::forward<Args>(aArgs)..., 5);
}

int main()
{
    post_forwarder(foo, 6, 6.1); // Compilation error on instantiation
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我怀疑这个问题与variadic模板参数在fixed int参数之前的函数类型中展开的事实有关,但如果是这种情况我就找不到合理的理由.

Clang 3.6报告的错误是:

error: no matching function for call to 'post_forwarder'
note: candidate template ignored: failed template argument deduction
Run Code Online (Sandbox Code Playgroud)

Bar*_*rry 7

争论推论在这里失败:

template <class... Args>
void post_forwarder(void(*fun)(Args..., int), Args&&... aArgs)
                           //  ^^^^^^^
Run Code Online (Sandbox Code Playgroud)

一般来说,参数包必须在最后才能被推导出来.通常的解决方案是将其包装在不可推导的上下文中,以便甚至不尝试推导:

template <typename T>
struct identity {
    using type = T;
};

template <class... Args>
void post_forwarder(void(*fun)(typename identity<Args>::type..., int), Args&&... aArgs)
{
    fun(std::forward<Args>(aArgs)..., 5);
}
Run Code Online (Sandbox Code Playgroud)

  • @TC 是的,但现在它是一个**超级**非推导的上下文。[另外,我没有完整的解释] (2认同)