특정 인터페이스를 구현하는 유형을 허용하는 템플릿을 만들 수 있습니까? 예를 들어, 템플릿 사용자에게 말하고 싶습니다. Init() 및 Destroy() 메소드를 구현하는 동안에는 컨테이너에 아무 것도 저장할 수 있습니다.인터페이스를 시행하는 템플릿
감사합니다.
특정 인터페이스를 구현하는 유형을 허용하는 템플릿을 만들 수 있습니까? 예를 들어, 템플릿 사용자에게 말하고 싶습니다. Init() 및 Destroy() 메소드를 구현하는 동안에는 컨테이너에 아무 것도 저장할 수 있습니다.인터페이스를 시행하는 템플릿
감사합니다.
은 개념의 제한된 하위 집합 (의도적이지만 불행히도 단편화 된) C++ 0x 기능을 제공합니다. 필요한 인터페이스 용으로 concept check class을 만들어서 활용할 수 있습니다.
C++ 0x 기능은 무엇입니까? 개념은 상처를주지 않았다. –
피트 : 사실. 나는 "잠재적 인, 그러나 결국"C++ 0x 기능을 제거했다. –
+1 불행히도 우리는 오랫동안 이것을 받아 들여야 할 것입니다 ... –
아니요, 불가능합니다.
템플릿은 유형으로 바뀌며 많은 차이가 없습니다.
모든 가능한 멤버가 상속해야하는 기본 클래스를 만들고 모든 템플릿을 그대로 두는 것이 좋습니다.
기본적으로 C++에서 지원되지 않는 existential types을 소개합니다.
음, 템플릿 인수에 Init()
및 Destroy()
을 호출하는 방법을 정의 할 수 있으며 어떻게 든이 메서드를 디버그 모드로 호출 할 수 있습니다.
또는 인터페이스를 정의하고 템플릿 구현에서이 인터페이스로 캐스팅 할 수 있습니다. 이것은 릴리스 모드에서도 사용할 수 없습니다.
첫 번째로 Init 및 Destroy가 필요하면 템플릿 코드가이를 사용한다는 뜻입니다. 즉, 유형이 해당 메소드를 가지고 있지 않으면 템플릿이 컴파일되지 않으므로 컴파일러에서 이미 존재 여부를 확인합니다. 당신이 그 (것)를 확인하려면
그러나 다음 방법 중 하나는, 어떤 컴파일시의 맥락에서 자신의 주소를 사용할 수 있습니다 예를 들어
는 꼬모으로 출력은template <class T>
class X
{
private:
template <unsigned N>
struct Number {};
Number<sizeof(&T::Init) + sizeof(&T::Destroy)> must_define_init_and_destroy();
};
struct A
{
bool Init();
void Destroy();
};
struct B {};
int main()
{
X<A>();
X<B>();
}
:
"ComeauTest.c", line 7: error: class "B" has no member "Init"
Number<sizeof(&T::Init) + sizeof(&T::Destroy)> must_define_init_and_destroy();
^
detected during instantiation of class "X<T> [with T=B]" at line 21
"ComeauTest.c", line 7: error: class "B" has no member "Destroy"
Number<sizeof(&T::Init) + sizeof(&T::Destroy)> must_define_init_and_destroy();
^
detected during instantiation of class "X<T> [with T=B]" at line 21
그러나 필요한 방법 중 하나에 과부하가 걸리면이 문제가 발생하며 자연히이 방법이 적합한 프로토 타입인지 테스트하지 못합니다.
예 : bool Init (int, int). 정확한 서명을 확인하기 위해 static_cast를 사용할 수는 있지만 다시 말하면 유형에 대한 불필요한 제한이있을 수 있습니다. 예를 들어, 어떤 클래스에 bool Init (long, long)이 있다면 어떻게 될까요?
이러한 노력은 오류 메시지를보다 명확하게 만 드러내는 데 필요한 것 같습니다. 그러나, 나는 당신이 달리 개념 체크없이 얻을 수있는 메시지 ("여기에 사용될 때 T = X로 초기화하는 적합한 초기화 메소드가 없다")가 그렇게 나쁘다는 것을 매우 의심합니다.
예, 가능합니다.
그러나 매우 복잡합니다 (고급 템플릿 메타 프로그래밍) 전체 개념은 "대체 오류가 C++ 템플릿의 오류 (SFINAE)"품질을 기반으로 작성되었습니다.
은 본질적으로, 당신은 'template <typename T, void (T::*)()>'
같은 것을 사용하여 템플릿과 벡터에 <T, T::Init>
를 사용하여 인스턴스화 할 수 있습니다. 대체가 존재하지 않으면 대체 오류가 발생합니다 (대신 SFINAE 원칙이 생성자를 대신 사용하기 때문에 여기에서 사용됩니다).
이것은 물론 간략한 설명입니다. 죄송합니다. 현재 더 좋은 서비스를 제공 할 수 없지만 this discussion을보고 싶을 수도 있습니다. has_member 및 is_call_possible을 검색하십시오.
도움이되기를 바랍니다.
오렌은
사실, 그 반대의 : 템플릿이 Init()
및 Destroy()
을 필요로하는 경우, 그것은 하지이 두 가지를 가지고 모든 유형을 인스턴스화하는 것은 불가능하다.
템플릿과 관련된 유일한 문제는 요구 사항이 암시 적이라는 것입니다 (즉 템플릿이 템플릿 내에서 필요한 지점에서 컴파일되지 않음). 명시 적이 아닙니다. 즉 컴파일러가 인스턴스화 시점). 개념은 그것을 고치려고했지만 얼마 전에 그들은 taken out of the next standard입니다.
이것은 http://stackoverflow.com/questions/1550370/c-polymorphic-class-template의 복제본입니다.하지만이 질문은 더 잘 쓰여지고 일반적입니다. =) – gnud
이 질문을 이해하는 방법을 모르십니까? 컨테이너에 정확히 하나의 유형 (메소드를 지원함) 또는 다른 유형의 요소가 저장됩니까? – Dario
컨테이너는 필수 인터페이스를 상속하고 구현 한 유형을 제공하는 모든 유형의 요소를 저장합니다. 예를 들어, 컨테이너는 요소가 삽입/제거 될 때 Element.Init() 및 Element.Destroy()를 호출 할 수 있습니다. – jackhab