문제

일종의 임의의 질문 ...

내가 찾고있는 것은 캐스트에서 제시 한 클래스 인스턴스의 정의 된 연산자를 사용하는 캐스트 작업을 표현하는 방법이며, 유형에 대한 정의 된 캐스트 연산자가없는 경우 컴파일 타임 오류를 생성합니다. 예를 들어, 내가 찾고있는 것은 다음과 같습니다.

template< typename RESULT_TYPE, typename INPUT_TYPE >
RESULT_TYPE operator_cast( const INPUT_TYPE& tValue )
{
    return tValue.operator RESULT_TYPE();
}

// Should work...
CString sString;
LPCTSTR pcszString = operator_cast< LPCTSTR >( sString );

// Should fail...
int iValue = 42;
DWORD dwValue = operator_cast< DWORD >( iValue );

흥미로운 사이드 노트 : 위의 코드는 VS2005 C ++ 컴파일러를 충돌시키고 VS2008 C ++ 컴파일러에서 컴파일러 버그라고 생각하기 때문에 VS2008 C ++ 컴파일러에서 올바르게 컴파일하지 않지만 아이디어를 보여주기 바랍니다.

이 효과를 달성하는 방법을 아는 사람이 있습니까?

편집 : 더 많은 근거, 왜 이것을 사용할 수 있는지 설명합니다. 유형을 캡슐화하거나 추상화 해야하는 래퍼 클래스가 있으며 캡슐화 된 유형으로 캐스팅하고 있습니다. static_cast <>을 사용할 수는 있지만 실패하기를 원할 때 작동 할 수 있습니다 (예 : 컴파일러는 해당 연산자가 존재하지 않기 때문에 실패를 원할 때 요청한 유형으로 변환 할 수있는 연산자를 선택합니다).

분명히 드문 경우이지만, 캡슐화 된 기능에서 컴파일러가 원하는 것을 정확하게 표현할 수 없다는 것은 성가신 일입니다. 따라서 여기서 질문입니다.

도움이 되었습니까?

해결책

게시 한 코드는 Cameau 컴파일러 (일반적으로 유효한 C ++임을 잘 표시합니다).

유효한 캐스트는 하나 이상의 사용자 정의 캐스트로 구성되어 있으므로 내가 생각했던 가능한 솔루션은 캐스트 템플릿에서 새 유형을 정의하고 정적 인제 새 유형에서 결과 유형까지의 캐스트가 없습니다 (사용 부스트 is_convertible) 그러나 이것은 캐스트 연산자와 캐스트 생성자 (하나의 인수가있는 CTOR)를 구별하지 않으며 추가 캐스트가 발생합니다 (예 : void* 에게 bool). 캐스트 연산자와 캐스트 생성자를 구별하는 것이 옳은 해야 할 일이지만 그것이 질문이 말한 것입니다.

며칠 후에 이것을 으르렁 거리는 소리가 나를 때렸다. 이것은 C ++의 털이 멤버 구문에 대한 털이 많은 포인터로 인해 말보다 약간 쉽습니다 (예상보다 오래 걸렸습니다). 이것이 VS2008에서 작동하는지 모르겠습니다. Cameau에서만 확인했습니다.

template< typename Res, typename T>
Res operator_cast( const T& t )
{
    typedef Res (T::*cast_op_t)() const;
    cast_op_t cast_op = &T::operator Res;
    return (t.*cast_op)();
}

편집하다: VS2005 및 VS2008에서 테스트 할 기회가있었습니다. 내 연구 결과는 원래 포스터와 다릅니다.

  • VS2008에서 원본 버전은 제대로 작동하는 것 같습니다 (내 것과 마찬가지로).
  • VS2005에서 원래 버전은 내장 유형 (예 : int to int)에서 캐스팅 할 때 컴파일러가 충돌합니다.

다른 팁

변환 생성자를 사용하여 표시됩니다 명백한 컴파일러가 암시 적으로 변환 된 유형이 래퍼 클래스를 초기화하지 못하게하는 방법입니다.

템플릿 관련 컴파일러 오류 메시지는 일반적으로 풀릴 수있는 완전한 고통이므로, 각 변환을 지정하는 것이 마음에 들지 않으면 기본 템플릿 정의를 제공하여 실패 케이스에서보다 유익한 메시지를 방출 할 수 있습니다. 이것은 컴파일러가 실제로 호출 된 템플릿에서 코드를 컴파일하려고한다는 사실을 사용합니다.

#include <string>

// Class to trigger compiler warning   
class NO_OPERATOR_CONVERSION_AVAILABLE
{
private:
   NO_OPERATOR_CONVERSION_AVAILABLE(){};
};

// Default template definition to cause compiler error
template<typename T1, typename T2> T1 operator_cast(const T2&)
{
   NO_OPERATOR_CONVERSION_AVAILABLE a;
   return T1();
}

// Template specialisation
template<> std::string operator_cast(const std::string &x)
{
   return x;
}

템플릿 전문화를 원하는 것 같습니다.

/* general template */
template<typename T1, typename T2> T1 operator_cast(const T2 &x);

/* do this for each valid cast */
template<> LPCTSTR operator_cast(const CString &x) { return (LPCTSTR)x; }

편집 : 다른 게시물에서 언급했듯이, 지원되지 않는 캐스트가 수행되면 더 유용한 오류 메시지를 제공하기 위해 일반 버전에 무언가를 넣을 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top