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);
的类型来覆盖编译器推导过程,但是为什么我需要这样做呢?
发布于 2017-09-19 12:45:53
这是一种类型推断的冲突。T
从第一个参数推导为int
,从第二个参数推导为const int
。因此,类型推断失败(编译器显示一条消息,该消息可能清楚也可能不清楚根本原因)。
如果要使该函数工作,而不必显式指定模板参数,则可以使其只由第二个函数参数驱动演绎:
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
而不作任何修改。
发布于 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‘)
https://stackoverflow.com/questions/46300736
复制相似问题