C++ Can';不使用函数名距离

C++ Can';不使用函数名距离,c++,C++,以下代码编译得很好: #include <string> int dist(std::string& a, std::string& b) { return 0; } int main() { std::string a, b; dist(a, b); return 0; } #包括 int dist(std::string&a,std::string&b){ 返回0; } int main(){ std::字符串a,b; 区(甲,乙);; 返回

以下代码编译得很好:

#include <string>

int dist(std::string& a, std::string& b) {
  return 0;
}

int main() {
  std::string a, b;
  dist(a, b);
  return 0;
}
#包括
int dist(std::string&a,std::string&b){
返回0;
}
int main(){
std::字符串a,b;
区(甲,乙);;
返回0;
}
但当我将函数从dist重命名为distance时:

#include <string>

int distance(std::string& a, std::string& b) {
  return 0;
}

int main() {
  std::string a, b;
  distance(a, b);
  return 0;
}
#包括
整数距离(标准::字符串和a,标准::字符串和b){
返回0;
}
int main(){
std::字符串a,b;
距离(a,b);
返回0;
}
我在编译(gcc 4.2.1)时遇到此错误:

/usr/include/c++/4.2.1/bits/stl_iterator_base_types.h:在“std::iterator_traits”的实例化中:
b、 cpp:9:从此处实例化
/usr/include/c++/4.2.1/bits/stl_iterator_base_types.h:129:错误:“struct std::basic_string”中没有名为“iterator_category”的类型

为什么我不能命名函数距离?

原因是存在一个被调用的标准算法,该算法由ADL(参数相关查找)发现:尽管您的调用不符合
std
命名空间,但参数的类型
a
b
(即
std::string
)与
std::distance
函数(即
std
)位于同一命名空间中,因此也考虑使用
std::distance()
来解决重载问题

如果确实要调用函数
distance()
(我建议您不要这样做),您可以将其放在自己的命名空间中,然后在调用时完全限定函数名,或者将其保留在全局命名空间中并以这种方式调用:

    ::distance(a, b);
//  ^^
但是,请注意,如果标准库的实现提供了一个SFINAE友好版本的
迭代器_traits
(更多详细信息,请参阅)

通过对
iterator\u traits
的SFINAE友好实现,编译器应该认识到
std::distance()
函数模板(因为它是一个模板)在给定类型为
std::string
的参数时无法实例化,因为它的返回类型:

template< class InputIt >
typename std::iterator_traits<InputIt>::difference_type 
//       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//       Trying to instantiate this with InputIt = std::string
//       may result in a soft error during type deduction if
//       your implementation is SFINAE-friendly, and in a hard
//       error otherwise.
    distance( InputIt first, InputIt last );
template
类型名称std::迭代器特征::差异类型
//       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//尝试使用InputIt=std::string实例化此
//在类型推断过程中可能会导致软错误,如果
//您的实现是SFINAE友好的,并且在一个困难的环境中
//否则会出错。
距离(先输入,后输入);
在这种情况下,编译器只需出于重载解析的目的放弃此模板,然后选择
distance()
函数

但是,如果标准库的实现没有提供SFINAE友好版本的
迭代器_traits
,则在不符合SFINAE条件的上下文中可能会发生替换失败,从而导致(硬)编译错误


这显示了您使用GCC4.8.0编译的原始程序,它附带了一个libstdc++版本,该版本实现了一个SFINAE友好的
迭代器

,如果
使用名称空间std,这不应该是一个问题吗出现了?所以我只需要选择另一个名字?没有办法命名我的函数距离?@TimothyShields:没有,这是因为依赖于参数Lookup@ThomasMatthews:所有名称都是std::都是小写。如果您的姓名约定使用混合大小写,您就不能与std::@TimothyShields冲突,如果它不存在,
std::我能马上知道问题出在哪里吗。要是我早3个小时到就好了。英雄联盟
template< class InputIt >
typename std::iterator_traits<InputIt>::difference_type 
//       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//       Trying to instantiate this with InputIt = std::string
//       may result in a soft error during type deduction if
//       your implementation is SFINAE-friendly, and in a hard
//       error otherwise.
    distance( InputIt first, InputIt last );