과부하 해결 알고리즘에서 모호성은 어떻게 결정됩니까?
오버로딩 해결 방법을 이해하려고합니다.
이것이 모호한 이유 :
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:
- Exact match: no conversion required, lvalue-to-rvalue conversion, qualification conversion, user-defined conversion of class type to the same class
- Promotion: integral promotion, floating-point promotion
- 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.
'Programing' 카테고리의 다른 글
크롬의 sqlite (0) | 2020.12.02 |
---|---|
WebStorm / PHPStorm의 스마트 탭은 무엇을합니까? (0) | 2020.12.02 |
C #에서 이중 디스패치? (0) | 2020.12.02 |
애플리케이션에 어떤 자바 스크립트 엔진을 삽입 하시겠습니까? (0) | 2020.12.02 |
long double vs double (0) | 2020.12.02 |