다중 상속 클래스 멤버 구별
다음 가변 기본 클래스 템플릿을 고려하세요.
<code class="cpp">template <typename... Types> class Base { public: template <typename T> typename std::enable_if<Contains<T, Types...>::value>::type foo() { std::cout << "Base::foo()\n"; } };
foo() member는 Types 팩의 유형 중 하나와 일치하는 템플릿 매개변수로만 호출할 수 있습니다. 이제 겹치지 않는 기본 유형으로 파생 클래스를 정의해 보겠습니다.
<code class="cpp">struct Derived : public Base<int, char>, public Base<double, void> {};</code>
Derived().foo
컴파일러가 모호성을 해결할 수 없는 이유:
멤버 조회 [class.member.lookup]에 대한 병합 규칙은 다음과 같이 명시합니다. 파생 클래스에 빈 선언 세트(멤버 없음)가 있는 경우 모든 기본 클래스의 조회 세트를 병합해야 합니다. 우리의 경우 기본 클래스의 선언 세트가 다르기 때문에 병합이 실패합니다.
해결책:
이러한 모호성을 피하기 위해 파생 클래스에 using 선언을 추가할 수 있습니다. class:
<code class="cpp">struct Derived : public Base<int, char>, public Base<double, void> { using Base<int, char>::foo; using Base<double, void>::foo; };</code>
파생 클래스에 foo의 오버로드를 도입함으로써 병합 규칙을 효과적으로 우회합니다.
수집기 클래스 사용:
또는 템플릿 클래스를 사용하여 모든 기본 클래스의 using 선언을 집계할 수 있습니다.
<code class="cpp">template <typename... Bases> struct BaseCollector; template <typename Base, typename... Bases> struct BaseCollector<Base, Bases...> : Base, BaseCollector<Bases...> { using Base::foo; using BaseCollector<Bases...>::foo; }; struct Derived : BaseCollector<Base2<int>, Base2<std::string>> {};</code>
이 접근 방식은 using 선언의 팩 확장을 허용하므로 C 17에서 컴파일하는 것이 더 효율적입니다.
위 내용은 Variadic 템플릿 멤버 함수를 호출할 때 C에서 다중 상속 모호성이 발생하는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!