首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >传递const类型地址时模板参数推导失败

传递const类型地址时模板参数推导失败
EN

Stack Overflow用户
提问于 2017-09-19 12:41:40
回答 2查看 538关注 0票数 14
代码语言:javascript
运行
复制
template <typename T>
T go(T a, T *b){ T *t; return *t;}

int main() {
    const int x = 10;
    go(x, &x);
    return 0;
}

给出编译器错误:

错误:调用‘go( const &,const*)’没有匹配函数

为什么第一个参数是引用类型const int&而不是const int

为了修复这个编译错误,我通过指定参数go<const int>(x, &x);的类型来覆盖编译器推导过程,但是为什么我需要这样做呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-09-19 12:45:53

这是一种类型推断的冲突。T从第一个参数推导为int,从第二个参数推导为const int。因此,类型推断失败(编译器显示一条消息,该消息可能清楚也可能不清楚根本原因)。

如果要使该函数工作,而不必显式指定模板参数,则可以使其只由第二个函数参数驱动演绎:

代码语言:javascript
运行
复制
template <class T>
struct NonDeduced { using type = T; }

template <class T>
T go(typename NonDeduced<T>::type a, T *b) { T *t; return *t; }

这样,T将只能从第二个参数中还原,而第一个参数将使用推导出来的T而不作任何修改。

票数 13
EN

Stack Overflow用户

发布于 2017-09-19 12:46:54

因为a被声明为通过值传递,所以在模板参数推导

否则,如果A是cv限定类型,则忽略顶级cv限定符以进行扣减:

这意味着,对于go(x, &x);,对于第一个参数x,模板参数T将被推断为int,而不是const int。对于第二个参数,T将被推断为const int,因为b被声明为通过指针传递(并且被指向的对象上的cv-限定符是保留的;通过引用传递也会发生同样的事情)。那推论就失败了。

顺便说一句:嘎吱声给出了非常明确的信息:

prog.cc:4:3:注意:忽略候选模板:推导参数'T‘的冲突类型('int’vs. 'const‘)

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46300736

复制
相关文章

相似问题

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