메소드 매개 변수의 자동 변환을 방지하기 위해 키워드를 사용하여 명시 적으로 사용할 수 있습니까?

StackOverflow https://stackoverflow.com/questions/175689

문제

유형의 자동 변환을 방지하기 위해 클래스 생성자에 C ++ 키워드 '명시 적'을 사용할 수 있다는 것을 알고 있습니다. 이 동일한 명령을 사용하여 클래스 메소드의 매개 변수 변환을 방지 할 수 있습니까?

나는 두 명의 클래스 멤버가 있는데, 하나는 부울을 매개 변수로, 다른 하나는 서명되지 않은 int입니다. int로 함수를 호출했을 때 컴파일러는 매개 변수를 bool로 변환하고 잘못된 메소드라고 불렀습니다. 나는 결국 Bool을 대체 할 것임을 알고 있지만, 지금은이 새로운 루틴이 개발되면서 다른 루틴을 깨고 싶지 않습니다.

도움이 되었습니까?

해결책

아니요, 명시 적 사용할 수는 없지만 대신 할 수 있습니다.

class ClassThatOnlyTakesBoolsAndUIntsAsArguments
{
public:
  void Method(bool arg1);
  void Method(unsigned int arg1);

  // Below just an example showing how to do the same thing with more arguments
  void MethodWithMoreParms(bool arg1, SomeType& arg2);
  void MethodWithMoreParms(unsigned int arg1, SomeType& arg2);

private:
  template<typename T>
  void Method(T arg1);

  // Below just an example showing how to do the same thing with more arguments
  template<typename T>
  void MethodWithMoreParms(T arg1, SomeType& arg2);
};

취하는 모든 방법에 대해이 패턴을 반복하십시오 bool 또는 unsigned int. 메소드의 템플릿 버전에 대한 구현을 제공하지 마십시오.

이렇게하면 사용자는 항상 부울 또는 부호없는 INT 버전을 명시 적으로 호출해야합니다.

전화하려는 시도 Method 다른 유형이 있습니다 bool 또는 unsigned int 가시성 규칙에 대한 표준 예외 (물론 친구, 내부 통화 등)에 따라 회원이 개인이기 때문에 컴파일에 실패합니다. 액세스가있는 것이 개인 메소드를 호출하면 링커 오류가 발생합니다.

다른 팁

아니. explicit 컨텍스트에 관계없이 특정 클래스 간의 자동 변환을 방지합니다. 물론 내장 수업을 위해 할 수 없습니다.

다음은 강력한 typedef를 만드는 데 사용할 수있는 매우 기본적인 래퍼입니다.

template <typename V, class D> 
class StrongType
{
public:
  inline explicit StrongType(V const &v)
  : m_v(v)
  {}

  inline operator V () const
  {
    return m_v;
  }

private:
  V m_v; // use V as "inner" type
};

class Tag1;
typedef StrongType<int, Tag1> Tag1Type;


void b1 (Tag1Type);

void b2 (int i)
{
  b1 (Tag1Type (i));
  b1 (i);                // Error
}

이 접근법의 좋은 특징 중 하나는 동일한 유형의 다른 매개 변수를 구별 할 수도 있다는 것입니다. 예를 들어 다음을 가질 수 있습니다.

class WidthTag;
typedef StrongType<int, WidthTag> Width;  
class HeightTag;
typedef StrongType<int, HeightTag> Height;  

void foo (Width width, Height height);

'foo'의 고객에게 어떤 주장이 있는지 분명합니다.

당신에게 효과가있는 것은 템플릿을 사용하는 것입니다. 다음은 템플릿 함수를 보여줍니다 foo<>() 전문 bool, unsigned int, 그리고 int. 그만큼 main() 함수는 통화가 어떻게 해결되는지 보여줍니다. 상수를 사용하는 호출은 유리합니다 int 유형 접미사를 지정하지 않으면 해결됩니다 foo<int>(), 따라서 오류 호출이 나타납니다 foo( 1) 당신이 전문화하지 않는다면 int. 이 경우 문자 그대로의 정수 상수를 사용하는 발신자는 다음을 사용해야합니다. "U" 통화를 해결하기 위해 접미사 (이것은 원하는 동작 일 수 있음).

그렇지 않으면 전문화해야합니다 int 그리고 사용하십시오 "U" 접미사 또는 캐스트에 캐스트합니다 unsigned int 그것을 전달하기 전에 unsigned int 버전 (또는 아마도 당신이 원하는 것이라면 값이 음수가 아니라고 주장 할 수도 있습니다).

#include <stdio.h>

template <typename T>
void foo( T);

template <>
void foo<bool>( bool x)
{
    printf( "foo( bool)\n");
}


template <>
void foo<unsigned int>( unsigned int x)
{
    printf( "foo( unsigned int)\n");
}


template <>
void foo<int>( int x)
{
    printf( "foo( int)\n");
}



int main () 
{
    foo( true);
    foo( false);
    foo( static_cast<unsigned int>( 0));
    foo( 0U);
    foo( 1U);
    foo( 2U);
    foo( 0);
    foo( 1);
    foo( 2);
}

컴파일러는 "모호한 호출"경고를 주었다.

나는 TDD 개발을하고 있었고 Mock Object에서 해당 호출을 구현하는 것을 잊지 않았다.

bool은 0 또는 1으로 제한되는 int입니다. 이것은 리턴 0의 전체 개념입니다. 이것은 논리적으로 return false를 말하는 것과 동일합니다. (코드에서 이것을 사용하지 마십시오).

Bool One을 호출하는 int 버전을 쓸 수도 있습니다.

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