C ++에서 부정확 한 상호 변형을 코딩하는 방법은 무엇입니까?
-
21-08-2019 - |
문제
먼저 예 :
template <class HashingSolution>
struct State : public HashingSolution {
void Update(int idx, int val) {
UpdateHash(idx, val);
}
int GetState(int idx) {
return ...;
}
};
struct DummyHashingSolution {
void UpdateHash(int idx, int val) {}
void RecalcHash() {}
};
struct MyHashingSolution {
void UpdateHash(int idx, int val) {
...
}
void RecalcHash() {
...
UpdateHash(idx, GetState(idx)); // Problem: no acces to GetState function, can't do recursive application of templates
...
}
};
이 예에서는 주정부가 주 클래스에 통과 할 수 있으므로 주가 해시 폴리언스의 방법에 액세스 할 수 있지만 해시 폴리시는 GetState를 호출 할 수 없습니다. 이 문제를 해결할 수 있습니까?
이것은 가장 깊은 루프입니다. 여기에서 가상 기능은 성능을 25%이상 떨어 뜨립니다. 인라인은 저에게 중요합니다.
해결책
JALF가 의견에서 제안한 것처럼, 당신은 아마도 다음의 변형을 사용하고 싶을 것입니다. 호기심으로 되풀이되는 템플릿 패턴 (CRTP). 즉, 만들어집니다 MyHashingSolution
파생 클래스별로 매개 된 클래스 템플릿 :
template <typename D>
struct MyHashingSolution {
typedef D Derived;
void UpdateHash(int idx, int val) {
...
}
void RecalcHash() {
...
UpdateHash(idx, derived().GetState(idx));
...
}
private:
// Just for convenience
Derived& derived() { return *static_cast<Derived*>(this); }
};
이 경우 파생을 원하기 때문에 State
클래스도 템플릿이 되려면 약간의 특이한 단계를 취해야합니다. State
a 템플릿 템플릿 매개 변수:
template <template <class T> class HashingSolution>
struct State : public HashingSolution<State<HashingSolution> > {
typedef HashingSolution<State<HashingSolution> > Parent;
void Update(int idx, int val) {
Parent::UpdateHash(idx, val); // g++ requires "Parent::"
}
int GetState(int idx) {
return ...;
}
};
핵심 요점은 제공되는 것입니다 State
상속 HashingSolution<State<HashingSolution> >
, Derived
파생 된 클래스입니다 HashingSolution<State<HashingSolution> >
그래서 static_cast<Derived*>(this)
다운 캐스트 HashingSolution<State>::derived()
올바르게 컴파일하고 작동합니다. (당신이 엉망이되고 파생된다면 State
~에서 HashingSolution<SomeOtherType>
대신 전화를받는 것을 시도하십시오. derived()
, 컴파일러는 요구 사항으로 불만을 제기합니다 static_cast<>
충족되지 않습니다.)
그런 다음 콘크리트를 선언하십시오 State
그렇게 사용하려는 클래스 :
typedef State<MyHashingSolution> MyState;
불행히도이 솔루션은 변경 해야하는 부작용이 있습니다. DummyHashingSolution
템플릿 템플릿 인수로 사용할 수 있도록 하나의 템플릿 인수를 무시하는 템플릿으로 (그리고 그러한 다른 유형) 하나의 템플릿 인수를 무시하는 템플릿.
다른 팁
어둠 속에서의 샷으로, 질문에 거의 정보가 거의 부족하다는 점을 고려할 때 (주석 참조) : 템플릿이 유용합니까? 그들은 종종 컴파일 타임 다형성에 좋습니다.
더 잠재적으로 유용한 정보를 얻으려면 문제를 더 설명하십시오. 문제 의견을보십시오. 기본 디자인을 계속 진행할 때 어떤 미세 최적화가 필요한지 아는 이유를 알려주십시오. 컴파일 또는 실행 환경에 대한 비정규 적 스트림이 있으면 몇 가지 세부 정보를 제공하십시오.