Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.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++ 使用非常量指针调用函数会在使用常量指针的函数上调用模板函数_C++ - Fatal编程技术网

C++ 使用非常量指针调用函数会在使用常量指针的函数上调用模板函数

C++ 使用非常量指针调用函数会在使用常量指针的函数上调用模板函数,c++,C++,以下代码是在g++4.1.2和g++4.4.4上编译的。两者都给出了评论中提到的结果 int f(const int * a) { return 0; } template<typename A> int f(A a) { return 1; } int main() { int x; // return f(&x); // returns 1 return f((const int *)&x); // returns 0 }

以下代码是在g++4.1.2和g++4.4.4上编译的。两者都给出了评论中提到的结果

int f(const int * a)
{
   return 0;
}

template<typename A>
int f(A a)
{
   return 1;
}

int main()
{
    int x;
    // return f(&x); // returns 1
    return f((const int *)&x); // returns 0
}
intf(常数int*a)
{
返回0;
}
模板
INTF(A)
{
返回1;
}
int main()
{
int x;
//返回f(&x);//返回1
返回f((常量int*)&x);//返回0
}
它似乎可以归结为调用
f(int*)
解析为
f(int*)
,而不是预期的
f(const int*)
。我觉得这令人震惊,完全不直观


这是G++中的一个bug,C++的一个暗角,还是因为某种原因我失踪了?如果它不是一个bug,那么它背后的理论或逻辑是什么?关于这个问题有什么安全的做法吗?

那么,在调用
f(&x)
的情况下,为什么要调用const版本的函数“expected”

如您所知,参数类型是
int*
。因此,函数的
f(int*)
版本比
f(const int*)
版本更匹配,因为前者的参数类型完全匹配。编译器看到了从模板生成
f(int*)
的机会,并抓住了这个机会。这就是它在C++中的工作原理。p> 如果模板版本与非模板版本一样好,则非模板版本通常获胜。但在这种情况下,如果模板版本明显更好,则模板版本将获胜


显然,您希望编译器选择函数的非模板版本。为什么?

对于实例化的模板
f
不需要转换(
int*
->
const int*
),因此它是一个更好的匹配-实际上,它是一个精确匹配,只会输给非模板精确匹配,这是第二次调用的情况


<> P.>对“更好匹配”规则的完整解释可在C++标准的“3.3.3”中获得。 > f(int)和<代码> f(const int)<代码>是相同的原型,只要ANSI C++编译器是一致的,但是<代码> f(INT*) >与<代码> f(const int *)/f(int const)可能不一样。链接:+1提供一个最小的完整示例程序。看看为什么这是个好主意。@sehe“也许”?我认为你误读了那个环节的讨论。“foo(int*const a)”接受一个指向int的常量指针。在这里的示例中,“f(const int*a)”接受指向int的指针。由于一个简单的隐式常量转换,我希望它会赢。在我看来,const升级指针类型总是在考虑模板之前进行,这似乎是明智的。也许有一个例子说明了为什么这不是一个好主意。@Roland:No conversion>overload resolution中的琐碎转换。@Roland:假设您有两种方法来执行一个操作。(就其论点而言)它是破坏性的。因此,在
const
版本中,您需要首先执行参数的副本,这显然效率较低。示例:
T&&operator+(T&&,T const&)
T operator+(T const&,T const&)
更有效。在这种情况下,我同意,因为它们都是模板。我的意思是,在考虑任何模板之前,我希望隐式常量转换。