2012-04-23 3 views
10

편집 : Mike Seymour의 의견에 따라 operator std::string() const;operator char *() const;으로 바꿔 그에 따라 구현을 변경했습니다. 이것은 암시 적 캐스팅을 허용하지만 어떤 이유에서든 unsigned long int 연산자가 char * 연산자보다 우선합니다.이 연산자는 옳은 느낌이 들지 않습니다 ... 또한 char *와 같은 불쾌한 C 요소를 노출하고 싶지 않습니다. 클래스, 때 std :: string. 내 CustomizedInt 클래스가 원하는 기능을 지원하기 위해 몇 가지 요소를 상속해야한다는 생각이 들었습니다. 아무도 std::basic_string에 관한 마이크의 의견을 자세히 설명해 주시겠습니까? 내가 제대로 이해하는지 모르겠다.C++ 암시 적 변환 연산자 우선 순위

#include <string> 
#include <sstream> 
#include <iostream> 

class CustomizedInt 
{ 
private: 
    int data; 
public: 
    CustomizedInt() : data(123) 
    { 
    } 
    operator unsigned long int() const; 
    operator std::string() const; 
}; 

CustomizedInt::operator unsigned long int() const 
{ 
    std::cout << "Called operator unsigned long int; "; 
    unsigned long int output; 
    output = (unsigned long int)data; 
    return output; 
} 

CustomizedInt::operator std::string() const 
{ 
    std::cout << "Called operator std::string; "; 
    std::stringstream ss; 
    ss << this->data; 
    return ss.str(); 
} 

int main() 
{ 
    CustomizedInt x; 
    std::cout << x << std::endl; 
    return 0; 
} 

"123 INT 긴 호출 연산자 부호"인쇄 :


나는이 코드 조각이있다. 내 질문은 다음과 같습니다.

  1. unsigned long int 연산자를 제거한 후에 x를 std :: string으로 명시 적으로 변환해야하는 이유는 무엇입니까? 왜 암시 적 캐스트 연산자 (std :: string)를 직접 호출하지 않습니까?
  2. 어떤 암시 적 캐스트가 허용되며 우선 순위는 무엇인지 설명하는 설명서가 있습니까? unsigned long int 연산자와 함께이 클래스에 unsigned int 연산자를 추가하면 < < 연산자에 대한 컴파일러 오류가 발생합니다.
  3. 또한 이러한 연산자를 정의하는 것이 가난한 관행이지만 관련된 경고 사항을 완전히 이해하고 있는지 확신 할 수 없습니다. 누군가가 그들을 윤곽을 그릴 수 있을까요? 공용 메서드 ToUnsignedLongInt 및 ToString을 정의하는 것이 더 나은 방법일까요? 내가 운영자 부호없는 긴 INT를 제거한 후
+0

관련이 있습니다 : [문자열로 암시 적 변환을 통해 객체를 스트리밍 할 때의 오버로드 해결 실패] (http://stackoverflow.com/questions/6677072/overload-resolution-failure-when-streaming-object-via-implicit-conversion -to-str) –

+0

@Als : 천천히 가져 가자. 아직 템플릿으로 들어가기 위해 준비가 안됐다. :) –

답변

8

, 내가 왜 수 std :: 문자열을 명시 적으로 X를 캐스팅해야합니까? 왜 암시 적 캐스트 연산자 (std :: string)를 직접 호출하지 않습니까?

문자열 << 버전

std::basic_string 템플릿의 파라미터에 의해 parametrised 주형 ( std::string 자체에 해당 템플릿의 특수화이다)이다. 이는 인수 종속 조회에서만 선택할 수 있으며 인수가 실제로 std::basic_string의 특수화이지 변환 할 수있는 것이 아닌 경우에만 작동합니다.

어떤 암시 적 캐스트가 허용되며 우선 순위는 무엇인지 설명하는 설명서가 있습니까?

규칙은 매우 복잡하므로 전체 기사를 보려면 C++ 표준을 읽어야합니다. 암묵적인 변환은 암시 적 변환에 둘 이상의 사용자 정의 변환을 포함 할 수 없으며 암시 적 변환 결과를 인수 종속 조회로 템플릿 전문을 선택하는 데 사용할 수 없다는 것을 알았습니다.

관련주의 사항을 완전히 이해하고 있는지 잘 모르겠습니다. 누군가가 그들을 윤곽을 그릴 수 있을까요?

나는 그것들을 완전히 이해하지 못한다. 암시 적 변환, 이름 조회 및 템플리트 전문화 (및 지금 당장 생각할 수없는 다른 요인들) 간의 상호 작용은 다소 복잡하며 대부분의 사람들은 모든 것을 배우려는 경향이 없습니다.암시 적 변환이 발생하지 않는 경우와 예상하지 못할 때 발생할 수있는 경우가 있습니다. 개인적으로, 나는 암시 적 변환을 피하는 것이 더 쉽다는 것을 대부분 발견했다.

ToUnsignedLongInt 및 ToString 공용 메서드를 정의하는 것이 더 좋을까요?

원하지 않는 전환을 피하기 위해 좋습니다. 당신이 그들을 떠나하여 문제를 해결하고 필요한 경우 명시 적으로 사용할 수 있습니다 그들은 단지 이러한 방식으로 사용할 수 있도록

std::cout << std::string(x) << std::endl; 

C++ 11에서, 당신은 그들에게 explicit를 선언 할 수 있습니다. 당신이 할 수있는 경우에 내 의견으로는, 그것은 제일 선택권 일 것입니다; 그렇지 않으면 명시 적 변환 함수를 사용하는 것이 좋습니다.

그런데 반환 유형이 main() 인 것은 void이 아니라 int이어야합니다.

+0

마이크 : 그런 자세한 설명을 해주셔서 감사드립니다. 그것은 약간의 것들을 정리합니다. 또한 "void main"이라는 작은 문제를 발견해 주셔서 감사합니다. 나는 정확한 버전을 사용하는 것을 기억해야한다. :) –