C++ 涉及非推断参数包的函数指针参数类型的模板参数推断
这类似于,但更为具体。这一次,没有编译器按预期工作C++ 涉及非推断参数包的函数指针参数类型的模板参数推断,c++,c++11,language-lawyer,variadic-templates,template-argument-deduction,C++,C++11,Language Lawyer,Variadic Templates,Template Argument Deduction,这类似于,但更为具体。这一次,没有编译器按预期工作 template<class T> struct nondeduced { using type = T; }; template<class T> using nondeduced_t = typename nondeduced<T>::type; template<class... T, class U> void f(void(*)(nondeduced_t<T>..
template<class T>
struct nondeduced
{
using type = T;
};
template<class T>
using nondeduced_t = typename nondeduced<T>::type;
template<class... T, class U>
void f(void(*)(nondeduced_t<T>..., U)) {}
void g(int, char) { }
int main()
{
f<int>(g); // error?
}
因为参数packT
已经根据
非推断上下文为:
- 不在参数声明列表末尾出现的函数参数包
template<class... T>
void f(void(*)(nondeduced_t<T>..., char)) {}
模板
void f(void(*)(非派生的,字符)){}
同样,这两种方法都不起作用:
template<class... T>
void f(void(*)(T..., char)) {}
模板
void f(void(*)(T…,char)){
我的期望是错误的吗?由一个未推断的上下文引起
不在参数声明列表末尾出现的函数参数包
不作为模板函数的最后一个参数出现的参数包永远不会被推断,但完全可以指定禁用推断的参数类型。e、 g
template<class T1, class ... Types> void g1(Types ..., T1);
g1<int, int, int>(1,2,3); // works by non-deduction
g1(1,2,3) // violate the rule above by non-deduced context
模板无效g1(类型…,T1);
g1(1,2,3);//非扣除作品
g1(1,2,3)//通过非推断上下文违反上述规则
但改变函数参数的顺序,即使保留模板参数不变,也会去除未推导的上下文条件,打破参数包的无限扩展。e、 g
template<class T1, class ... Types> void g1(T1, Types ...);
g1(1,2,3) // works because its a deduced context.
模板无效g1(T1,类型;
g1(1,2,3)//之所以有效,是因为它是一个推导出的上下文。
代码无法编译有两个原因:
template<class... T,class U>
void f( void(*)(U,T...) ) { }
f(g);
模板
无效f(无效(*)(U,T…){}
f(g);
或者更改模板参数的顺序,并在函数调用时指定模板参数,如下所示
template<class U,class... T>
void f( void(*)(U,typename nondeduced<T>::type...) ) {}
f<int,char>(g);
模板
void f(void(*)(U,typename非派生::type…){}
f(g);
有人请在这里帮我学习一下。我本以为模板void f(void(*)(非导出的,U)){
格式不正确,因为首先出现的是可变参数包。@CPPFREFERENCE中的AndyG:这似乎不是由SPECCCI明确指定的。请相信T.
在标准下应该是贪婪的-它不应该为U
消费留下任何东西,因此没有歧义。是吗?这是正常的吗?它们在问题中是非故意推断的。您不能通过更改前提条件来回答问题。
template<class U,class... T>
void f( void(*)(U,typename nondeduced<T>::type...) ) {}
f<int,char>(g);