首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >涉及非推导参数包的函数指针参数类型的模板参数推导

涉及非推导参数包的函数指针参数类型的模板参数推导
EN

Stack Overflow用户
提问于 2016-08-23 15:05:51
回答 1查看 853关注 0票数 14

这与问题类似,但情况更为具体。这一次,编译器不像预期的那样工作。

代码语言:javascript
复制
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?
}

在上面的示例中,不能推导参数pack T,但是编译器应该能够在使用显式参数替换pack T (本例中是单个int )之后推断出U

在没有nondeduced_t技巧的情况下,上面的操作也是可行的:

代码语言:javascript
复制
template<class... T, class U>
void f(void(*)(T..., U)) {}

因为根据T,参数包[temp.deduct.type]p5已经处于非推导的上下文中。

未推导的上下文如下:

  • 一个函数参数包,它不会出现在参数声明列表的末尾。

不幸的是,我测试过的编译器(g++/clang)都不接受该代码。值得注意的是,下面这样的内容既适用于g++也适用于clang。

代码语言:javascript
复制
template<class... T>
void f(void(*)(nondeduced_t<T>..., char)) {}

再说一次,这两种方法都行不通:

代码语言:javascript
复制
template<class... T>
void f(void(*)(T..., char)) {}

我的期望错了吗?

EN

回答 1

Stack Overflow用户

发布于 2016-08-23 21:30:58

[temp.deduct.type]p5提供的非推导上下文之一是

一个函数参数包,它不会出现在参数声明列表的末尾。

不作为模板函数的最后一个参数出现的参数包永远不会被推导出来,但是指定禁用演绎的参数类型是完全正确的。e.g

代码语言:javascript
复制
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

但是,改变函数参数的顺序,甚至保留模板参数,消除了非推导的上下文条件,打破了参数包的无限扩展。e.g

代码语言:javascript
复制
template<class T1, class ... Types> void g1(T1, Types ...);
g1(1,2,3)                 // works because its a deduced context.

您的代码不编译有两个原因:

  1. 函数参数的顺序创建了一个非推导的上下文,这将导致函数f中所述模式中的参数pack的类型-T-将永远不会被推导出来。
  2. 模板参数T只显示为函数参数(例如nondeduced_t)中的限定符,而不是直接指定为函数参数(允许参数推导)。

为了使代码编译,您可以放置参数包的展开,因为它忘记了nondeduced_t间接,如

代码语言:javascript
复制
template<class... T,class U>
void f( void(*)(U,T...) ) { }

f(g);

或更改模板参数的顺序并在函数调用中指定模板参数,如

代码语言:javascript
复制
template<class U,class... T>
void f( void(*)(U,typename nondeduced<T>::type...) ) {}

f<int,char>(g);    
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39104749

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档