Programing

과부하 해결 알고리즘에서 모호성은 어떻게 결정됩니까?

crosscheck 2020. 12. 2. 08:02
반응형

과부하 해결 알고리즘에서 모호성은 어떻게 결정됩니까?


오버로딩 해결 방법을 이해하려고합니다.

이것이 모호한 이유 :

void func(double, int, int, double) {}
void func(int, double, double, double) {}

void main()
{
    func(1, 2, 3, 4);
}

하지만 이건 아니야?

void func(int, int, int, double) {}
void func(int, double, double, double) {}

void main()
{
    func(1, 2, 3, 4);
}

첫 번째 경우에는 정확히 일치하는 항목 2 개와 정확히 일치하는 항목 3 개에 대해 2 개의 변환이 있고 두 번째 경우에는 정확히 일치하는 항목 3 개와 정확히 일치하는 항목 3 개에 대한 변환이 1 개 있습니다.

그렇다면 하나는 모호하고 하나는 그렇지 않은 이유는 무엇입니까? 여기서 논리는 무엇입니까?


과부하 해상도 규칙은 모든 경기의 세트에 부분적인 순서를 정의 - 과부하가있는 경우 F1보다 더 나은 일치하지 않습니다 F2, 그것은 그 의미하지는 않습니다 F2보다 더 나은 경기입니다 F1. 정확한 부분 순서는 k인수의 수가 인 차원 에서 두 점을 비교하는 것으로 생각할 수 있습니다 k. k-희미한 공간의 점에서이 부분 순서를 정의 해 보겠습니다 (x_1, x_2,..., x_k) < (y_1, y_2,..., y_k) if x_i <= y_i for all i and x_j < y_j for at least one j. 이것은 표준에서 정의한 후보 비 템플릿 함수에 대한 부분 순서입니다.

예를 살펴 보겠습니다.

void func(double, int,    int,    double) {}
                  vvv     vvv       vvv
                 better  better    equal
void func(int,    double, double, double) {}
          vvv                       vvv
         better                    equal

따라서 어떤 과부하도 다른 것보다 엄격히 낫습니다.

두 번째 예에서 :

void func(int,   int,   int,   double) {}
          vvv    vvv    vvv     vvv
         equal  better better  equal
void func(int, double, double, double) {}
          vvv
         equal

이제 첫 번째 오버로드는 하나의 인수를 제외하고 모두 두 번째보다 낫고 두 번째보다 결코 나쁘지 않습니다. 따라서 모호함이 없습니다. 부분 순서는 실제로 첫 번째 순서를 더 잘 선언합니다.

(위의 설명은 함수 템플릿을 고려하지 않았습니다. 자세한 내용은 cppreference 에서 확인할 수 있습니다 .)


표준 (§ [over.match.best] / 1)의 표현은 다음과 같습니다.

[...] ICS i (F)는 목록 i 번째 인수 를 실행 가능한 함수 F i 번째 매개 변수 유형으로 변환하는 암시 적 변환 시퀀스를 나타냅니다 .
[...] 실행 가능한 함수 F1은 다음과 같습니다. 모든 인수 i 에 대해 ICS i (F1)이 ICS i (F2) 보다 나쁜 변환 시퀀스가 ​​아닌 경우 다른 실행 가능한 함수 F2보다 더 나은 함수로 정의 된 다음
— 일부 인수 j 에 대해 ICS j (F1)가 a ICS j (F2) 보다 더 나은 변환 순서

첫 번째 경우 두 함수가 첫 번째 테스트에 실패합니다. 첫 번째 인수의 경우 첫 번째 함수 (taking double)는 두 번째 함수 보다 변환 시퀀스가 ​​더 나쁩니다. 두 번째 인수의 경우 두 번째 함수는 첫 번째 함수보다 더 나쁜 변환 시퀀스를 갖습니다 (다시 한 번, 한 경우에는 int승격되어야 double하지만 다른 경우에는 안됨).

따라서 두 함수 모두 첫 번째 규칙을 통과하지 못하고 호출이 모호합니다.

두 번째 함수 쌍 사이에서 첫 번째 함수에 대한 모든 인수는 적어도 두 번째 함수에 대한 일치하는 인수만큼 좋은 변환을 갖습니다. 그런 다음 두 번째 규칙으로 넘어 가서 첫 번째 함수가 두 번째 함수보다 더 나은 변환 (승진 대신 정체성)을 갖는 인수가 하나 이상 있음 (사실상 두 개)이 있음을 확인합니다.

Therefore, the first function is a better match, and will be selected.


Ambiguity is determined by the ranking:

  1. Exact match: no conversion required, lvalue-to-rvalue conversion, qualification conversion, user-defined conversion of class type to the same class
  2. Promotion: integral promotion, floating-point promotion
  3. Conversion: integral conversion, floating-point conversion, floating-integral conversion, pointer conversion, pointer-to-member conversion, boolean conversion, user-defined conversion of a derived class to its base

Exact match wins vs Promotion which wins vs Conversion.

In the example:

void func(int, bool, float, int){cout << "int,bool,float,int" << endl;}
void func(int, bool, int, int){cout << "int,int,int,int" << endl;}

int main()
{
    func(1,1,3.4,4);
}

Argument 1(1) is an exact match on both
Argument 2(1) is an exact match on both
Argument 3(3.4) can be converted into float and int - Ambiguity Neither is better.
Argument 4(4) is an exact match on both

But if we did this: func(1,1,3.4f,4);
(3.4f) is now an exact match!
void func(int, bool, float, int) then wins the battle.

참고URL : https://stackoverflow.com/questions/29090692/how-is-ambiguity-determined-in-the-overload-resolution-algorithm

반응형