2013-03-02 2 views
0
template <typename T> struct s 
{ 

}; 

template <> struct s<MyClass *> 
{ 

}; 

... in main function 
struct s<MyClass*> obj; 

위의 코드는 컴파일하지만 난 정말 하나가 총 전문화와 함께 무엇을 할 수 있는지템플릿 매개 변수의 클래스 포인터 -이게 유용할까요?

template <> struct s<MyClass *> 
{ 

}; 

내가

template <> struct s<MyClass *obj > // ERROR 
{ 

}; 
처럼 (상수 또는 정적도) 포인터 변수를 추가 할 수 없습니다 볼 수 없습니다

위 전문화의 요지는 무엇입니까?

s<int> s1; 
s<float> s2; 
s<MyClass> s3; 

이러한 개체는 각 템플릿 s의 인스턴스화 될 것입니다 : 당신은 (암시 적 또는 명시 적으로) 템플릿을 인스턴스화 할 때 난 당신이 유형을 제공하는 MyClass에 * "익명"포인터

+0

아마도 'MyClass *'의 맞춤 동작이 필요한 경우 유용할까요? –

+2

이 질문과 이전 질문을 바탕으로 : 템플릿의 전체 개념 *을 오해 한 것일 수 있습니다. 그것들은 * compile-time * 구조체입니다. – delnan

답변

1

나는 당신은 아마 여기에 오해가

template <> struct s<MyClass *obj > // ERROR 
[...] 

처럼 (상수 또는 정적도) 포인터 변수를 추가 할 수 없습니다. 사용자 정의 클래스의 인스턴스에 대한 포인터를 유형이 아닌 템플릿 매개 변수로 제공하려는 사용 사례에 관심이있는 경우 템플릿 특수화과는 아무 관련이 없습니다.

: 특히

, 당신은 는 C++ 11 표준의 14.3.2/1 항에 따라, 템플릿 인수로 클래스의 글로벌 인스턴스에 대한 포인터를 지정할 수 있다는 생각

비 유형에 대한 템플릿 인수 비 서식 템플레이트 매개 변수 중 하나가 될 것이다 :

- 정수 또는 열거 형의 비 형 템플릿 매개 변수에 대해, 변환 상수 식 (5.19) 템플릿 매개 변수 유형의; 또는

- 비 형식 템플릿 매개 변수의 이름. 또는

- 상수 식 지정 (5.19) 기능 템플릿 및 기능 템플릿 ID가 포함 정적 저장 기간과 외부 또는 내부 링크 또는 외부 또는 내부 링크와 기능을 가진 개체의 주소하지만 비정규 클래스 멤버를 제외하고, & id-expression으로 표현 (괄호는 무시). 이름이 함수 또는 배열을 참조하는 경우 &을 생략 할 수 있으며 해당 템플릿 매개 변수가 참조 인 경우 을 생략해야합니다. 또는

[...]

이것은 당신이 달성하기 위해 노력하고 있었는지 아마 : 템플릿 특수화 대한 정보

struct MyClass { }; 

MyClass c; 

template<MyClass* p> 
//  ^^^^^^^^ Non-type template argument 
struct s 
{ 
    // Possibly work with p 
}; 

int main() 
{ 
    s<&c> obj; 
} 

:

코드에 관하여 당신이 쓴, 기본 템플릿 처리 어떤 유형 :

template <typename T> struct s 
{ 
    // Definition... 
}; 

그리고이 명시 적 전문화 (이 기술 이름이 아닌 "총"전문입니다) 인수가 기본 템플릿을 인스턴스화하는 데 사용 할 때 기본 템플릿의 내용을 다시 정의 할 수 있습니다 MyClass*입니다 :

template <> struct s<MyClass *> 
{ 
    // Definition when the template argument is `MyClass*` 
}; 

예를 들어, 당신이 할 수 있습니다 :

struct MyClass { }; 

template <typename T> struct s 
{ 
    void print() { cout << "Primary template!" << endl; } 
}; 

template <> struct s<MyClass *> 
{ 
    void print() { cout << "Specialization for MyClass*!" << endl; } 
}; 

int main() 
{ 
    s<int> obj; 
    obj.print(); // Will print "Primary template!" 

    s<MyClass*> obj; 
    obj.print(); // Will print "Specialization for MyClass*!" 
} 

알 그래서 전문 템플릿의 정의는 기본 템플릿의 정의에서완전히 다를 수 있다는주의 사항 :

물론
template <typename T> struct s 
{ 
    void print() { cout << "Primary template!" << endl; } 
}; 

template <> struct s<MyClass *> 
{ 
    void greet() { cout << "Specialization for MyClass*!" << endl; } 
}; 

int main() 
{ 
    s<int> obj; 
    obj.print(); // Will print "Primary template!" 

    s<MyClass*> obj; 
    obj.greet(); // Will print "Specialization for MyClass*!" 
    obj.print(); // ERROR! s<MyClass*> has no `print()` member function 
} 

는,이 클래스 템플릿 특수화가 작동하는 방법의 단지 예입니다. 기본 템플릿과 특수 템플릿의 정의를 구별 한 것처럼 유용하게 사용할 수있는 방법은 없습니다.

그러나 실제 사용 사례가 많이 있습니다. 예를 들어, 일반 알고리즘은 특정 유형에 대해 완전히 다른 방식으로 최적화 및 재 작성 될 수 있습니다.

템플릿 특수화의 또 다른 중요한 응용 프로그램은 형질을 정의하는 것입니다.이 특성은 읽을 수도 있습니다.

0

을 사용할 수 없습니다 T은 각각 int, floatMyClass으로 추측됩니다. s2 구성원 유형 floatx라고했다

template <typename T> struct s { 
    T x; 
}; 

가 다음 객체 s1 구성원 유형 intx라고 갖고, s3는 부재 형 x라고있다 : 예를 들어, s 경우 사실과 같이 정의 된 MyClass.

당신이 준으로 명시 적 전문화의 포인트는 템플릿 매개 변수에 전달 된 유형에서와 같이 MyClass*s의 다른 구현을 제공하는 것입니다

: 예를 들어

s<MyClass*> s4; 

명시 적으로 고려, 보이는 전문화 같은 :

template <> struct s<MyClass*> 
{ 
    int x; 
}; 

s4, 그 템플릿 인수는 MyClass*에도 불구하고, 회원이 유형의 x라는 것이다 객체 int. 우리는 구체적으로 말했습니다. "템플릿 인자 타입이 MyClass* 일 때, 구조체는 멤버 int x을 가질 것입니다."

s4 개체는 일반 버전이 아닌 s의 명시적인 특수화를 사용합니다. 템플릿 인수가 MyClass* 인 경우 클래스를보다 효율적으로 구현할 수 있습니다.

관련 문제