2016-11-30 2 views
37
std::string tmp; 
tmp +=0;//compile error:ambiguous overload for 'operator+=' (operand types are 'std::__cxx11::string {aka std::__cxx11::basic_string<char>}' and 'int') 
tmp +=1;//ok 
tmp += '\0';//ok...expected 
tmp +=INT_MAX;//ok 
tmp +=int(INT_MAX);//still ok...what? 

첫 번째 인수는 정수를 인수로 전달한다고 주장합니다. 맞습니까? 왜 다른 사람들이 컴파일 작업을 통과해야합니까? Visual C++ 및 g ++에서 테스트 한 결과 위와 같은 결과가 나타납니다. 그래서 저는 표준에 의해 정의 된 것을 놓친다 고 생각합니다. 이게 뭐야?std :: string + = 연산자는 인수로 0을 전달할 수 없습니다.

+4

'int'는'char'으로 변환 될 것입니다. 그러나'0'에 대해서는'NULL' 또는'int 0'인지 여부를 알기가 어렵습니다. – Praveen

답변

46

리터럴 0은 널 포인터 상수입니다. 당신이 의미하는 경우 컴파일러는 알 수 없습니다 :

std::string::operator +=(const char*); // tmp += "abc"; 

또는

std::string::operator +=(char);   // tmp += 'a'; 

이 (더 나은 컴파일러 옵션 목록).

workround은 (당신이 발견 한 것처럼)로 APPEND 작성하는 것입니다 : (. 난 당신이 문자열 버전 싶지 않았다 가정 - tmp += nullptr; 런타임에 UB을 것을)

tmp += '\0'; 

+1

컴파일러가 정말로'+ = (char)'를 고려해야합니까? – Bathsheba

+12

예. 'char'는 정수형이고 정수는 char로 암시 적으로 변환 가능합니다. '+ = (char)'는 모호하지 않은 모든 경우에 * all * 호출되는 오버로드입니다. –

11

0 리터럴은 모든 포인터 유형으로 암시 적으로 변환 가능하므로 (각각의 널 포인터 상수가 생성됨) 따라서 연산자를 추가하는 std::string과 일치하는 두 개의 똑같이 유효한 변환 시퀀스가 ​​생성됩니다.