Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么可变模板参数的替换失败了?(在固定参数之前打包)_C++_Templates_C++11_Variadic Templates - Fatal编程技术网

C++ 为什么可变模板参数的替换失败了?(在固定参数之前打包)

C++ 为什么可变模板参数的替换失败了?(在固定参数之前打包),c++,templates,c++11,variadic-templates,C++,Templates,C++11,Variadic Templates,下面是一个触发编译错误的最小示例: #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

下面是一个触发编译错误的最小示例:

#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;
}

编辑:改写答案:

表单
Args…,int
不允许推断
Args…

此操作:

template <class F, class... Args>
void post_forwarder(F f, Args&&... aArgs) {
    f(std::forward<Args>(aArgs)..., 5);
}
模板
无效邮递货运代理(F、F、ARG和…AARG){

f(std::forward

参数推导在此处失败:

template <class... Args>
void post_forwarder(void(*fun)(Args..., int), Args&&... aArgs)
                           //  ^^^^^^^
模板
无效邮递货运代理(无效(*fun)(Args…,int),Args&…aArgs)
//  ^^^^^^^
对于参数包必须在末尾才能推断的一般规则,通常的解决方案是将其包装在不可推断的上下文中,以便甚至不尝试推断:

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);
}
模板
结构标识{
使用类型=T;
};
模板
void post_转发器(void(*fun)(typename identity::type…,int),Args&…aArgs)
{
乐趣(标准:前进(aArgs)…,5);
}

你能发布错误吗?这会很有帮助。顺便说一句,将
Args&&…
转发到所需的函数指针
Args…
不是一个好计划。只要确保你知道这一点。@Yakk我必须承认,我确实可以使用更多关于你提出的观点的细节:)@adn转发引用类型很少与您在完全不同的代码位中用来表示变量的类型完全相同。您使用从变量
a..
导出的转发引用类型来匹配不是从这些变量生成的函数指针。请考虑转发引用推断的4种情况,以及相应的函数指针必须是什么类型。如果这没有意义,请重新讨论转发引用的作用(这不是魔术),或者停止在最简单的上下文以外的任何情况下使用它们。你确定吗?在
fun
签名中有一个显式的last
int
,我希望它将
Args…
推断限制在前两个参数内。它确实有效,但问题是试图理解为什么建议的最小示例不起作用?(因为它是从一个更复杂的系统中提取出来的,您提出的替代方案无法替代预期的功能)@AdN抱歉,我有一些重要的东西,无法回答。这是一个不可推断的上下文,这就是它失败的原因。但你已经有了答案。从技术上讲,第一个
Args…
已经在一个非推断上下文中了。@t.C.是的,但现在它是一个超级非推断上下文。[还有,我没有完整的解释]。作为旁注,在这些上下文中,我真的更喜欢使用
identity
的别名,比如
dont_Destruction
,所以即使我不了解其机制,至少我知道其目的是什么。@t.C.如果它是非推断上下文,为什么它会失败?
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);
}