I am trying to wrap my head around template specialization, and I am a bit confused (perhaps not understanding what typename actually is, or what the compiler expects)

**Example 1 (Compiles):**

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

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

```

**Example 2 (Compiles):**

```
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(){}
};

```

**Example 3 (Fails):**

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

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

```

The error is:

*error: type/value mismatch at argument 2 in template parameter list for ‘template class Example*

**Questions:**

First, I am new to generic programming, and I hope I am asking the right questions. The compiler spec terminology is still a bit foreign to me.

* 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?
* What would be a "proper" method to specialize the class with int or enum?
* Am I asking the right questions?

Thank you

**EDIT/Solution:**

After I understood what is going on (from Yakk's explanation), here is how my final solution looks like. I read somewhere by one of the C++ guru's that "You can solve any problem by adding another layer of abstraction". Now I know what that means :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(){}
};

```

**And in main():**

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

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

```