GCC는 operator ++ ()와 operator ++ (int)를 구분할 수 없습니다.
template <typename CRTP>
struct Pre {
CRTP & operator++();
};
template <typename CRTP>
struct Post {
CRTP operator++(int);
};
struct Derived
: Pre<Derived>
, Post<Derived>
{};
int main() {
Derived d;
d++;
++d;
}
GCC에서 다음 오류가 발생합니다.
<source>: In function 'int main()':
<source>:18:10: error: request for member 'operator++' is ambiguous
d++;
^~
<source>:8:14: note: candidates are: CRTP Post<CRTP>::operator++(int) [with CRTP = Derived]
CRTP operator++(int);
^~~~~~~~
<source>:3:16: note: CRTP& Pre<CRTP>::operator++() [with CRTP = Derived]
CRTP & operator++();
^~~~~~~~
<source>:19:11: error: request for member 'operator++' is ambiguous
++d;
^
<source>:8:14: note: candidates are: CRTP Post<CRTP>::operator++(int) [with CRTP = Derived]
CRTP operator++(int);
^~~~~~~~
<source>:3:16: note: CRTP& Pre<CRTP>::operator++() [with CRTP = Derived]
CRTP & operator++();
^~~~~~~~
사전 감소 및 사후 감소 연산자는 유사한 오류를 발생시킵니다. Clang에는 그러한 오류가 없습니다. 무엇이 잘못되었거나이 문제를 해결하는 방법에 대한 아이디어가 있습니까?
이름 조회가 먼저 발생해야합니다. 이 경우 이름 operator++
.
[basic.lookup] (내 강조)
1 이름 조회 규칙은 문법이 허용하는 모든 이름 (typedef-names ([dcl.typedef]), namespace-names ([basic.namespace]) 및 class-names ([class.name]) 포함)에 균일하게 적용됩니다. 특정 규칙에 의해 논의되는 문맥에서 그러한 이름. 이름 조회는 이름의 사용을 해당 이름의 선언 ([basic.def])과 연결합니다. 이름 조회는 이름에 대한 명확한 선언을 찾습니다 ([class.member.lookup] 참조) . 이름 조회는 이름이 함수 이름 인 것을 발견하면 하나 이상의 선언을 이름과 연관시킬 수 있습니다. 선언은 오버로드 된 함수 집합 ([over.load])을 형성한다고합니다. 이름 조회가 성공한 후 오버로드 확인 ([over.match])이 발생합니다.. 액세스 규칙 (Clause [class.access])은 이름 조회 및 함수 오버로드 확인 (해당되는 경우)이 성공한 경우에만 고려됩니다. 이름 조회, 함수 오버로드 확인 (해당되는 경우) 및 액세스 검사가 성공한 후에 만 식 처리에서 추가로 사용되는 이름 선언에 의해 도입 된 속성이 있습니다 (Clause [expr]).
그리고 조회가 모호하지 않은 경우에만 오버로드 해결이 진행됩니다. 이 경우 이름은 서로 다른 두 클래스의 범위에서 발견되므로 과부하 해결 이전에도 모호성이 존재합니다.
[class.member.lookup]
8 오버로드 된 함수의 이름이 모호하지 않으면 액세스 제어 전에 오버로드 해결 ([over.match])도 발생합니다. 모호성은 종종 클래스 이름으로 이름을 한정하여 해결할 수 있습니다. [ 예:
struct A { int f(); }; struct B { int f(); }; struct C : A, B { int f() { return A::f() + B::f(); } };
— 최종 예]
The example pretty much summarizes the rather long lookup rules in the previous paragraphs of [class.member.lookup]. There is an ambiguity in your code. GCC is correct to report it.
As for working around this, people in comments already presented the ideas for a workaround. Add a helper CRTP class
template <class CRTP>
struct PrePost
: Pre<CRTP>
, Post<CRTP>
{
using Pre<CRTP>::operator++;
using Post<CRTP>::operator++;
};
struct Derived : PrePost<Derived> {};
The name is now found in the scope of a single class, and names both overloads. Lookup is successful, and overload resolution may proceed.
참고URL : https://stackoverflow.com/questions/54091513/gcc-cant-differentiate-between-operator-and-operatorint
'Nice programing' 카테고리의 다른 글
React에서 컴포넌트간에 기능을 공유하는 올바른 방법 (0) | 2020.12.05 |
---|---|
Linux USB : 전원 켜기 및 끄기? (0) | 2020.12.05 |
SQL Server로 Lucene.Net 구성 (0) | 2020.12.05 |
유사한 텍스트가있는 기사를 찾는 알고리즘 (0) | 2020.12.05 |
git : 두 가지 병합 : 어떤 방향? (0) | 2020.12.05 |