简体   繁体   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;
}

Gives compiler error: 给编译器错误:

error: no matching function for call to 'go(const int&, const int*)' 错误:没有用于调用'go(const int&,const int *)'的匹配函数

Why is the first argument a reference type const int& instead of just const int ? 为什么第一个参数是引用类型const int&而不是const int

To fix this compilation error, I overrode the compiler deduction process by specifying the type of arguments go<const int>(x, &x); 为了解决这个编译错误,我通过指定参数的类型来覆盖编译器推导过程go<const int>(x, &x); , but again why do I need to do that? ,但为什么我还需要这样做呢?

It's a conflict of type deduction. 这是类型演绎的冲突。 T is deduced as int from the first argument, and as const int from the second argument. T从第一个参数推导为int ,从第二个参数推导为const int Hence type deduction fails (and the compiler presents a message which may or may not make the underlying cause clear). 因此,类型推导失败(并且编译器呈现的消息可能会或可能不会使根本原因明确)。

If you want to make this function work without having to specify the template argument explicitly, you could make it so that only the second function argument drives the deduction: 如果你想使这个函数工作而不必明确指定模板参数,你可以使它只有第二个函数参数驱动扣除:

template <class T>
struct NonDeduced { using type = T; }

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

That way, T will only be deducible from the second argument, and the first parameter will use the deduced T without modification. 这样, T只能从第二个参数中推导出来,并且第一个参数将使用推导出的T而不进行修改。

Because a is declared to be passed by value, then in template argument deduction : 因为a声明是按值传递的,所以在模板参数推导中

c) otherwise, if A is a cv-qualified type, the top-level cv-qualifiers are ignored for deduction: c)否则,如果A是cv限定类型,则忽略顶级cv限定符以进行推导:

That means, for go(x, &x); 这意味着,对于go(x, &x); , for the 1st argument x , the template parameter T will be deduced as int , not const int . ,对于第一个参数x ,模板参数T将推导为int ,而不是const int For the 2nd argument T will be deduced as const int , because b is declared to be passed by pointer (and the cv-qualifiers on the object being pointed are reserved; the same thing happens for pass-by-reference). 对于第二个参数, T将被推导为const int ,因为b被声明为由指针传递(并且被指向的对象上的cv限定符被保留;对于传递引用也会发生同样的事情)。 Then deduction fails. 然后扣除失败。


BTW: clang gives quite clear message for it: BTW: clang给出了相当明确的信息:

prog.cc:4:3: note: candidate template ignored: deduced conflicting types for parameter 'T' ('int' vs. 'const int') prog.cc:4:3:注意:候选模板被忽略:推导出参数'T'的冲突类型('int'与'const int')

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

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