Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 传递常量类型的地址时模板参数推断失败 模板 T go(ta,T*b){T*T;return*T;} int main(){ 常数int x=10; go(x,&x); 返回0; }_C++_Templates_Compiler Errors_Constants - Fatal编程技术网

C++ 传递常量类型的地址时模板参数推断失败 模板 T go(ta,T*b){T*T;return*T;} int main(){ 常数int x=10; go(x,&x); 返回0; }

C++ 传递常量类型的地址时模板参数推断失败 模板 T go(ta,T*b){T*T;return*T;} int main(){ 常数int x=10; go(x,&x); 返回0; },c++,templates,compiler-errors,constants,C++,Templates,Compiler Errors,Constants,给出编译器错误: 错误:调用“go(const int&,const int*)”时没有匹配函数。 为什么第一个参数是引用类型const int&,而不仅仅是const int 为了修复这个编译错误,我通过指定参数类型go(x,&x)来覆盖编译器推导过程,但是我为什么要这样做呢?这是类型推断的冲突T从第一个参数推导为int,从第二个参数推导为const int。因此,类型推断失败(并且编译器会显示一条消息,该消息可能会也可能不会澄清根本原因) 如果要使此函数工作,而不必显式指定模板参数,则可以使

给出编译器错误:

错误:调用“go(const int&,const int*)”时没有匹配函数。

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


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

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

如果要使此函数工作,而不必显式指定模板参数,则可以使其仅由第二个函数参数驱动推导:

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

int main() {
    const int x = 10;
    go(x, &x);
    return 0;
}
模板
结构非派生{using type=T;}
模板
T go(typename非派生::type a,T*b){T*T;return*T;}

这样,
T
将只能从第二个参数中推导,第一个参数将使用推导出的
T
而不进行修改。

因为
a
被声明为按值传递,因此在:

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

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(x,&x)
,对于第一个参数
x
,模板参数
T
将被推断为
int
,而不是
const int
。对于第二个参数,
T
将被推断为
const int
,因为
b
被声明为通过指针传递(并且被指向的对象上的cv限定符被保留;通过引用传递也会发生同样的情况)。然后扣除失败


顺便说一句:给它一个非常明确的信息:

prog.cc:4:3:注意:已忽略候选模板:导出冲突 参数“T”的类型(“int”与“const int”的比较)


谢谢,这很有趣,但是考虑到它在内部执行的技巧,您认为这是一种很好的编程实践吗。@SauravSahu一旦您开始使用模板做一些非常重要的事情,您就会发现在某个地方必须有这样一个非派生的
。一旦你拥有了它,你也可以使用它。在这种特殊情况下,这是否是一个好主意,或者事情是否可以以不同的方式进行,很大程度上取决于
go
在您的实际用例中实际做了什么。我认为OP达到了叮当声消息给出的洞察力。他问为什么happens@sehe似乎OP关注错误消息的错误部分;我想告诉OP,关于模板演绎冲突的错误消息将有更多帮助。