2010-12-29 3 views
4

유형이 템플릿의 인스턴스 생성인지 확인하십시오.

 
struct RGBA (T) {/* ... */} 
struct BMPFile (DataT) if (is(DataT == RGBA)) {/* ... */} 

같은 구조체가 있지만 DataT 형식 및 RGBA 템플릿 때문에 is(DataT == RGBA) 작동하지 않습니다. 그 대신에 형식이 템플릿의 인스턴스화인지 확인해야

 
BMPFile!(RGBA!ushort) file; 

alias void isRGBAStructalias void isRGBAStruct

그건 해킹처럼 보입니다. 바라건대 std.traits가 이것을 다룰 것입니다.

+0

"작품 위에 아무것도"-> 당신이 얻을 오류가 무엇입니까? 그리고이 D 1.0 또는 D 2.0입니까? – Mehrdad

+1

나는 무엇이 올지 알 수 없다. 그러나 Bugzilla에서 유형이 특정 템플릿의 인스턴스인지 여부를 테스트하는 일반적인 방법에 대한 향상 요청을 만들었다. http://d.puremagic.com/ issues/show_bug.cgi? id = 5390 –

+0

Bugzilla에서 말한 것처럼 많은 uglies 해결 방법이 존재합니다. 'instantiationOf'가 있으면 편리 할 것입니다. –

답변

6

난 당신이 오버 구체적으로하려는 생각합니다. 내가 처리 할 수있는 방법은 어떤 유형의 인터페이스라도 구현할 수있는 한 DataT의 모든 유형을 허용하는 것입니다.

이는 D2 표준 라이브러리에서 수행되는 방법은, 저는 믿습니다, 형태의 다양한 속성을 테스트 IsIntegral 같은 템플릿을하는 것입니다.

예를 들어, DataT에 대한 요구 사항이 finangle 일 수 있다고 가정 해 봅니다. 다음과 같이 쓸 수 있습니다 :

위의 내용을 소금으로 채 웁니다. 테스트하지는 않았지만 그 기본 패턴이라고 생각합니다. 위의 내용에 익숙하지 않은 경우 주어진 익명 함수가 컴파일되는지 확인하는 것입니다. finangleDataT 일 경우에만 컴파일 할 수 있습니다.

+0

우수한 점. 일반적으로 템플릿은 정확한 유형이 아닌 API에 대해 걱정해야합니다. 이는 특정 유형이 특정 템플리트의 인스턴스인지 여부를 테스트해야하는 필요성을 없애고 일반적으로이를 처리하는 더 좋은 방법입니다. 그것은 특정 템플릿을 확인할 수 있도록 주기적으로 유용합니다. –

2

이것은 모두 메모리에서 가져온 것이므로 약간의 소금으로 복용하십시오.

먼저 구조체에 시체가 필요하므로 구문 분석 오류가 발생합니다. 둘째로 RGBA!ushort (유형)과 RGBA (템플릿)을 서로 다른 종류의 것으로 비교하려고하기 때문에 BMPFile의 템플릿 제약 조건이 작동하지 않습니다. 내가 마지막으로 확인한 (그리고 오랜 시간이 지났음) 유형이 주어진 템플릿의 인스턴스화인지를 확인할 수있는 확실한 방법은 없습니다.

+1

예 :-)'struct RGBA (T) {alias void isRGBAStruct; ...} 구조체 BMPFile (DataT) 경우 (이다 (DataT.isRGBAStruct)) {}' – FeepingCreature

+1

@FeepingCreature : ... '깨끗한'만 사람들이 제대로 따르는 경우 규칙의 선택된 값. – BCS

+0

감사합니다 @BCS, 나는 질문을 업데이 트했습니다. –

2

템플릿이 인스턴스화되면 자체의 짐승입니다.

struct RGBA(T) 
{ 
} 

과 같은 구조체가있는 경우 해당 구조체의 특정 인스턴스화가 해당 구조체의 인스턴스인지 직접 테스트 할 수 없습니다. is(RGBA!int == RGBA!int) 같은 것을 테스트하거나 (RGBA! T == RGBA! int)`(T가있는 경우), 제네릭 형식이 RGBA의 인스턴스인지 여부를 묻는 방법은 없습니다.

이유는 RGBA가 이 아니고 유형이기 때문입니다. 유형에 대한 템플릿입니다. 템플릿을 인스턴스화 할 때까지 유형이 존재하지 않으며 템플릿의 인스턴스화는 템플릿의 다른 인스턴스화와 관련이 없습니다. RGBA! int는 RGBA! float와 관련이 없습니다. 템플릿 제한 및 템플릿 전문화 등으로 인해 은 완전히 일 수 있습니다. 예 :

struct RGBA(T : int) 
{ 
    float a; 
    double b; 
    bool[] c; 
} 

struct RGBA(T : float) 
{ 
    @property int w() const pure nothrow 
    { 
     return 2; 
    } 
} 

이제 자신을 약간 제한하려는 경우 게임을 할 수 있습니다. 트릭은 RGBA를 인스턴스화하는 데 사용되는 T를 얻는 방법이 필요하다는 것입니다. 그래서,이 같은 작동합니다 :

import std.traits; 

struct RGBA(T) 
{ 
} 

struct BMPFile(DataT, T) 
    if(is(DataT == RGBA!T) && 
     IsIntegral!T) 
{ 
} 

지금,이 T가 또는 당신이 원하는하지 않을 수있는 일체형 인 제한이 있습니다. isFloatingPoint!()is(T == bool)처럼 작동하고 std.traits에는 많은 기능을, __traits에는 특징을 나타냅니다. 당신이 T가 될 것입니다 무엇의 몇 가지 아이디어가있을 경우 다음

struct BMPFile(DataT, T) 
    if(is(DataT == RGBA!T)) 

와 같은 짓을한다면, 당신은 지금

T.

의 종류를 확인하기 위해 적절한 제약 조건을 추가 할 수 있습니다 항상 타입 A를 준 두 번째로, 그것도 작동합니다 : BMPFile(RGBA!int, int) (하지만 나는 당신이 정말로 그것을하고 싶지 않다는 것을 짐작하고 있습니다).

또 다른 옵션은 T을 반환하거나 T을 사용하는 RGBA의 함수가있는 경우 해당 함수가 DataT에 있는지 여부를 테스트하고 특성을 사용하여 형식을 가져 오는 것입니다. 예 :

import std.traits; 

struct RGBA(T) 
{ 
    T func() { return T.init;} 
} 

struct BMPFile(DataT, T = ReturnType!(DataT.func)) 
    if(is(DataT == RGBA!T)) 
{ 
} 

그러나 당신이 그것을 func 기능이없는 뭔가를 통과 할 때, 그에 대한 오류 메시지가 꽤 추한 얻을 수 있고, RGBA에서 인스턴스가 아닌 다른 종류의 템플릿에 맞게 관리하는 경우, 그것은 ' 시도해 보거나 인스턴스화 할 수 있습니다. 작동하거나 작동하지 않을 수도 있지만, 두 경우 모두 원하는 것은 아닐 수도 있습니다.

그래서, 그것이 무엇에 내려 오는 것은이 직접 뭘 하려는지 할 수있는 방법은 현재 사용하지 않는,하지만 당신이 어떤 게임을하는 경우, 당신은 작동 뭔가를 얻을 수 있다는 것입니다. 본질적으로, 그것은 템플릿을 정의하기 위해 아래의 방법을 찾는에 오는 그런 당신은 당신이 테스트 할 수 있도록 (이 경우 RGBA) 첫 번째 템플릿을 인스턴스화하는 데 사용 된 인수에 액세스 할 수 있는지 여부를 두 번째로 주어진 유형 (DataT) 템플릿 (BMPFile)은 해당 유형 (RGBA!T)의 인스턴스입니다. T을받을 수 있다면 is(DataT == RGBA!T)을 테스트 할 수 있습니다.

+0

가장 완벽한 답변이되었으므로 여기에 다른 답변에 추가 한 주석을 추가하겠습니다.'struct RGBA (T) {alias void isRGBAStruct; ...} struct BMPFile (DataT) if (DataT.isRGBAStruct) {}' – FeepingCreature