문제

가장 가까운 이웃 쿼리를하는 코드를 작업하고 있습니다. 검색에서 사용자가 데이터를 쿼리 할 수있는 방법의 두 가지 간단한 아이디어가 있습니다.

  • 가장 가까운 N은 공간에서 주어진 지점을 가리 킵니다.
  • 주어진 거리 내의 모든 지점.

내 코드에서 포인트는 포인트리스트에 넣고 포인트리스트는 컨테이너가 검색에서 발견 된 포인트를 추적하는 역할을합니다.

지금 당장 내 PointList 객체에는 하나의 생성자가 있습니다.

PointList( unsigned int maxvals ); // #1

내가 추가하고 싶은 다음 두 생성자는 다음과 같습니다.

PointList( float maxdist ); // #2
PointList( unsigned int maxvals, float maxdist ); // #3

내 질문은 : 사용자와 C ++ 컴파일러가 PointList에 대한 올바른 생성자를 생성하고 생성자 1과 2를 구분하는 방법은 무엇입니까? #3을 구현하고 MaxVals 및 MaxDist에 대한 임의의 큰 값을 정의하는 상수를 제공해야합니까? 또 다른 대안은 목록에 포인트를 추가하기위한 논리를 지배하는 다른 가벼운 물체 시스템을 작성하는 것일 수 있지만, 이는 간단한 아이디어에 대한 과잉처럼 느껴집니다.

나는 공식 교육의 혜택없이 때때로 C ++를 배운 과학자 인 사용자 에게이 투명성을 만들려고 노력하고 있습니다. 감사!

도움이 되었습니까?

해결책

정수 유형에 대한 과부하 분해능은 두 가지 범주에서 발생하며, 이는 매우 대략 요약 할 수 있습니다.

  • 프로모션 : 이것은보다 작은 유형의 변환입니다. int 에게 int 또는 unsigned int, 여부에 따라 int 소스 유형의 모든 값을 저장할 수 있습니다.
  • 변환 : 이것은 모든 정수 유형에서 다른 정수 유형으로 변환됩니다.

유사하게, 부동 소수점 유형에 대한 변환은 두 가지 범주에서 발생합니다.

  • 프로모션 : 이것은 전환입니다 float 에게 double
  • 변환 : 이것은 모든 부동 소수점 유형에서 다른 부동 소수점 유형으로 변환됩니다.

그리고 정수에서 떠 다니거나 뒤로 변환됩니다. 이것은 프로모션보다는 전환으로 순위가 매겨집니다. 프로모션은 전환보다 순위가 매겨지며 프로모션이 필요한 경우 해당 사례가 선호됩니다. 따라서 다음 생성자를 사용할 수 있습니다

PointList( int maxVals );
PointList( unsigned int maxVals );
PointList( long maxVals );
PointList( unsigned long maxVals );

PointList( double maxDist );
PointList( long double maxDist );

모든 정수 유형의 경우 첫 번째 생성자 그룹을 선택해야합니다. 그리고 모든 부동 소수점 유형의 경우 두 번째 생성자 그룹을 선택해야합니다. 원래 두 생성자가 쉽게 모호하게 만들 수 있습니다. float 그리고 unsigned int, 당신이 통과하는 경우 int, 예를 들어. 다른 두 인수 생성자의 경우 원하는 경우 솔루션을 사용할 수 있습니다.


즉, 파라미터의 의미를 결정하는 것은 매우 깨지기 쉬우므로 공장 기능도 사용할 것입니다. 대부분의 사람들은 다음과 같은 결과가 동일 할 것으로 예상합니다

PointList p(floor(1.5));
PointList u((int)1.5);

그러나 그것은 다른 상황을 초래할 것입니다.

다른 팁

생성자 대신 공장 방법을 사용하지 않는 이유는 무엇입니까? 공장 방법은 사용자 정의 가능한 이름의 장점이 있습니다.


static PointList createNearestValues(unsigned int maxvals) {}
static PointList createByDistance(float maxdist) {}

사용을 고려하십시오 진정한 typedefs. 클라이언트 코드의 일부에 대해서는 조금 더 노력하지만 정확성이 보장됩니다.

첫 번째 및 PointList (10F)는 PointList (10)를 호출합니다.

두 번째는 10.0을 사용할 수도 있습니다.

생성자 #1과 #2가있는 경우 삽입 값이 float 또는 int이고 변환이 없으면 올바른 생성자가 호출됩니다. 따라서 명시 적으로 호출하는 데 사용하는 숫자의 유형을 만들 수 있습니다 (예 : 1F 및 1). 생성자 #3은 실제로 필요하지 않기 때문에 많은 옵션이 아닌 것 같습니다. 사용할 수있는 숫자에 대한 기본값이 필요한 경우

PointList(int max, float max=VALUE)

그리고

PointList(float max, int max=VALUE)

다시 : 이것은 코드 가독성 측면에서 코드보다 더 많은 해를 끼치는 것 같습니다.

이것은 좋은 독서를 요구하고 있습니다 과부하 해상도.

나는 확실히 사용할 것입니다 명백한 생성자. 예에서 서명되지 않은 정수는 암시 적으로 변환되지 않습니다.

class A
{
public:
    explicit A(float f){}
    explicit A(int i){}
};

void test(){
    unsigned int uinteger(0);
    A a1(uinteger);        //Fails, does not allow implicit conversions

    A a2((float)uinteger); //OK, explicit conversion

    float f(0.0);
    A a3(f);               //OK

    int integer(0);
    A a4(integer);         //OK
}

오류 메시지는 이해하기에 쉽습니다.

: error C2668: 'A::A' : ambiguous call to overloaded function
: could be 'A::A(int)'
: or       'A::A(float)'
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top