繁体   English   中英

传递const类型的地址时模板参数推断失败

[英]Template argument deduction failure while passing address of const type

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 int&,const int *)'的匹配函数

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

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

这是类型演绎的冲突。 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而不进行修改。

因为a声明是按值传递的,所以在模板参数推导中

c)否则,如果A是cv限定类型,则忽略顶级cv限定符以进行推导:

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


BTW: clang给出了相当明确的信息:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM