2017-02-07 2 views
0

내가 템플릿 특수화의 주위에 내 머리를 정리하려고 이해하지, 나는 조금 혼란 스러워요 (는 C++ 템플릿 전문화 그리고 상수

예 1 (아마도 무엇인가 실제로 유형 이름, 또는 컴파일러가 무엇을 기대하고 이해되지 않음) 컴파일)

template <typename A, typename... Args> 
class Example 
{ 
public: 
    Example(){} 
    virtual ~Example(){} 
}; 

template <typename A, typename... Args> 
class Example<A, int, Args...>{ 
    Example(){} 
    virtual ~Example(){} 
}; 

예 2 (컴파일)

template <typename A, int, typename... Args> 
class Example 
{ 
public: 
    Example(){} 
    virtual ~Example(){} 
}; 

template <typename A, typename... Args> 
class Example<A, 2, Args...>{ 
    Example(){} 
    virtual ~Example(){} 
}; 

예 3 (실패)

template <typename A, typename... Args> 
class Example 
{ 
public: 
    Example(){} 
    virtual ~Example(){} 
}; 

template <typename A, typename... Args> 
class Example<A, 2, Args...>{ 
    Example(){} 
    virtual ~Example(){} 
}; 

오류이다

오류 : 타입/'템플릿 클래스 템플릿 파라미터리스트에서 인자 2의 값이 일치 예

을 질문 :

우선, 저는 제네릭 프로그래밍을 처음 접했고, 나는 그에게 t 개의 질문. 컴파일러 사양 용어는 나에게 아직 조금 외견이다.

  • 무슨 일입니까? 컴파일러가 상수를 typename으로 처리하려고합니까?
  • typename을 int로 특수화 할 수 있고 int를 2로 특수화 할 수있는 이유는 typename을 2로 특수화 할 수없는 이유는 무엇입니까?
  • int 또는 enum을 사용하여 클래스를 특수화하는 "적절한"방법은 무엇입니까?
  • 올바른 질문을하고 있습니까?

    내가 (Yakk의 설명에서) 무슨 일이 일어나고 있는지 이해 한 후, 여기 내 최종 솔루션이 같은 모습입니다 :

당신에게

EDIT/솔루션을 감사드립니다. C++ 전문가 중 한 사람이 "다른 추상 레이어를 추가하여 문제를 해결할 수 있습니다."라고 읽었습니다. D

enum ETypes 
{ 
    UNKNOWN = 0, 
    INT = 1, 
    FLOAT = 2, 
    STRING = 3, 
    FUNC = 4, 
}; 

// This is to use the ETypes as a type. 
// Note that T is not a type, hence use it as RHS 
template<ETypes T> 
class ETypeName 
{ 
public: 
    ETypes type = T; 
}; 


// The example 
template <typename A, typename... Args> 
class Example 
{ 
private: 
    Example();    // Hide the constructor as private 
          // to generate compilation error 
    virtual ~Example(){} 
}; 


// LOOK! We can use the Enum to specialize the class. 
template <> 
class Example<ETypeName<ETypes::INT>>{ 
public: 
    ETypes mType; 
    Example():mType(ETypes::INT){} 
    virtual ~Example(){} 
}; 

를 메인에() : 지금은 그게 무슨 뜻인지

Example<ETypeName<ETypes::INT>> x; 

    // This can't happen. Private constructor. Not specialized yet 
// Example<ETypeName<ETypes::FLOAT>> x1; 
+1

비 유형 템플리트 매개 변수는 유형 템플리트 매개 변수와 다릅니다. 본질적으로 그렇습니다. 2는 유형이 아닌 매개 변수로 취급되지만 템플릿 클래스는 유형을 기대합니다. – user975989

+0

아, 그게 내가 빠졌던 것입니다. – Makketronix

답변

2

주된 전문은 다음과 같다 : 당신이 Example<stuff goes here>를 입력하면

template <typename A, typename... Args> 
class Example 

, 그것은 차 전문의 <typename A, typename... Args> 인수 목록과 일치 항상 입니다.

template <typename A, typename... Args> 
class Example<A, int, Args...> 

이 보조 전문입니다 :

이 완전히 다른 짐승이다. 여기서,

template <typename A, typename... Args> 

하지 인수 목록, 오히려 공제 목록입니다.

인수 목록은 다음과 같습니다 여기

class Example<A, int, Args...> 

. <> 사이에있는 것이 패턴 일치에만 사용되며 기본 전문화에 전달되는 인수에 대해.

형식 및 형식이 아닌 템플릿 매개 변수는 다른 것입니다. 1 차 전문화에서는 어떤 인수가 유형이고 어떤 인수는 유형이 아닌지를 자세히 설명합니다.

일단 주와 일치하면 각 보조 전문화는 인수와 패턴 일치됩니다. 유력한 후보자를 조사하고 합리적으로 복잡한 시스템을 사용하여 어느 것이 더 전문화되어 있는지를 결정합니다.이 규칙은 여기서 다루지 않을 것입니다.

+0

저는 정의와 용어를 명확히하고, 노출되지 않은 더 깊은 레벨에서 어떻게 작동하는지 설명하는 답변으로 이것을 받아들입니다. – Makketronix

2

What is happening? Is the compiler trying to treat the constant as typename?

예.

If typename can be specialized as int, and int can be specialized as 2, why can't a typename be specialized as 2?

typename으로 시작하는 템플릿 매개 변수에는 인수로 type이 필요합니다. 두 번째 예제에서 두 번째 템플릿 매개 변수는 이 아니라 int입니다. 따라서 인수로 유형을 예상하지 않지만 실제 값은 int입니다.

세 번째 예에서는 typename 템플릿 매개 변수 만 필요로하는 템플릿 정의를 사용하지만 사용자는 int 값을 인수로 사용합니다. 그래서 오류가 발생합니다.

What would be a "proper" method to specialize the class with int or enum?

잘 모르겠습니다. 질문의 의미를 올바르게 이해합니다. int 두 번째 템플릿 매개 변수를 사용하여 인스턴스 용 템플릿을 특수화하는 적절한 방법은 두 번째 템플릿 정의입니다.