2009-06-26 7 views
2

가장 가까운 이웃 쿼리를 수행하는 코드 작업 중입니다. 사용자가 검색에서 데이터를 쿼리하는 방법의 기초가되는 두 가지 간단한 아이디어가 있습니다.C에서 암시 적 유형 변환 관리

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

내 코드에서 Point는 PointList에 저장되고 PointList는 컨테이너로 검색시 발견 된 포인트를 추적합니다.

는 지금 내 PointList 객체 하나의 생성자했습니다

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

내 질문은 : 내가 추가 할

PointList(unsigned int maxvals); // #1 

다음 두 생성자이 얼마나 나는 것을 확인 할 내 사용자와 C++ 컴파일러는 PointList의 오른쪽 생성자를 생성하고 생성자 1과 2를 구별 할 수 있습니까? # 3을 구현하고 maxvals 및 maxdist에 대해 임의의 큰 값을 정의하는 상수를 제공해야합니까? 또 다른 대안은리스트에 포인트를 추가하는 로직을 관리하는 경량 오브젝트의 또 다른 시스템을 작성하는 것일 수도 있지만, 그런 단순한 아이디어의 경우 과잉으로 느껴질 수 있습니다.

나는 공식적인 교육의 혜택을받지 않고 C++을 배웠던 대부분의 과학자 들인 내 사용자에게이 사실을 투명하게 만들기 위해 노력하고 있습니다. 감사!

답변

5

과부하 해상도가 매우 약

  • 추진으로 요약 할 수있는 두 개의 범주에서 발생 :이 유형의 변환이다 int 모두 저장할 수 있는지 여부에 따라 int 또는 unsigned int에보다 작은 int 소스 타입의 값
  • 변환 : 이것은 정수 유형에서 다른 정수 유형으로의 변환입니다.

유사, 소수점 형식 부동의 전환은 두 가지 범주

  • 추진에서 발생 :이 double
  • 변환에 float에서 변환은 다음과 같습니다이 부동 다른 부동 소수점 형의 변환이다 포인트 유형

정수에서 부동 또는 뒤로 변환이 있습니다. 이것은 판촉보다는 오히려 전환으로 평가됩니다. 프로모션은 전환보다 순위가 높으며 프로모션 만 필요한 경우이 경우 우선합니다. 따라서 다음 생성자를 사용할 수 있습니다.

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

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

모든 정수 유형의 경우 생성자의 첫 번째 그룹을 선택해야합니다. 그리고 어떤 부동 소수점 유형에 대해서도 두 번째 생성자 그룹을 선택해야합니다. 예를 들어 int을 전달하면 원래 두 생성자가 floatunsigned int 사이의 모호성을 쉽게 초래할 수 있습니다. 다른 두 개의 인수 생성자의 경우 원하는 경우 솔루션과 함께 갈 수 있습니다.


그렇다면 매개 변수의 의미를 결정하는 것이 매우 취약하기 때문에 팩토리 함수도 사용하겠다고 생각합니다. 대부분의 사람들은 다음 결과가 동일 할 것으로 기대합니다.

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

그러나 다른 결과가 나올 수 있습니다.

1

첫 번째 PointList (10) 및 두 번째 PointList (10f)를 호출하십시오.

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

+0

,하지만 내 사용자가 차이를 이해하지 않을 수 있습니다. 그 중 일부는 컴파일러가 부동 소수점과 부호없는 int를 구별하는 방법에 대해 정교하지 않을 수 있습니다. –

6

왜 생성자 대신 팩토리 메소드를 사용합니까? 팩토리 메소드에는 사용자 정의 가능한 이름의 이점이 있습니다.

1

삽입 할 값이 float 또는 int이고 변환이 발생하지 않는 경우 생성자 # 1 및 # 2가있는 경우 올바른 생성자가 호출됩니다. 따라서 명시 적으로 호출하는 데 사용하는 숫자의 유형 (예 : 1f 및 1)을 지정하십시오. Constructor # 3은 실제로 필요하지 않으며 코드 사용자를 혼란스럽게하므로 많은 옵션이없는 것처럼 보입니다. 당신도 수에 대한 기본 값을해야하는 경우 다시

PointList(float max, int max=VALUE) 

PointList(int max, float max=VALUE) 

을 사용할 수 있습니다 :이 코드 가독성의 측면에서 다음 코드를 해를 더 할 것으로 보인다.

2

true typedefs을 사용해보십시오. 클라이언트 코드 부분에 약간의 노력이 있지만 정확성이 보장됩니다.

0

나는 명시 적으로 생성자를 사용합니다. 예제에서 부호없는 정수는 암시 적으로 변환되지 않습니다.

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)' 
확실히 가능성의