Template partial specialization

I want to write a template that combines two type of resources:
1
2
3
4
5
6
7
8
9
10
class someClasses
{
    typedef someType ElementType;
}

template<class T1,class T2>
class combo
{
    ...
}


And I want to specify my T1 and T2 has the same ElementType, how can I write my combo class to partial specialize the general case so the ElementType check is at compile time?
1
2
3
4
5
6
7
8
9
10
template< class T1,class T2 >
class combo
{
    ...
};

template< class T > class combo<T,T> // partial specialization; types are the same
{
    ...
};

I don't mean that, T1 T2 can be different, but their ElementType should match
This is one way:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <type_traits>

template< typename T1, typename T2,
          bool = std::is_same< typename T1::ElementType,
                               typename T2::ElementType>::value >
class combo
{
    //...
};

// partial specialization; ElementTypes are the same
template< typename T1, typename T2 > class combo< T1, T2, true >
{
    // ...
};
Thanks a lot!
And now I think of writing a private constructor in the general combo class to ban the mismatch ElementType code from compiling, but the error is somewhat hard to understand to the user of my code.
I Actually just want the partial specialization version to be generated by the compiler, is there any better way?
If you want clearer error messages, you can use static_assert in the class scope. I modified JLBorges' example:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <type_traits>

template< typename T1, typename T2,
          bool same = std::is_same< typename T1::ElementType,
                                    typename T2::ElementType>::value >
class combo
{
    static_assert(same, "T1::ElementType must be the same as T2::ElementType");
};

// partial specialization; ElementTypes are the same
template< typename T1, typename T2 > class combo< T1, T2, true >
{
    //actual class definition...
};
Though I don't think this is what you want (you are confusing me - how would you expect the compiler to generate either class automatically?)
Last edited on
This would suffice:
1
2
3
4
5
6
7
8
9
10
11
#include <type_traits>

template< typename T1, typename T2,
          bool = std::is_same< typename T1::ElementType,
                               typename T2::ElementType>::value >
class combo ; // not defined

template< typename T1, typename T2 > class combo< T1, T2, true >
{
    // ...
};


This would give a more cogent error diagnostic: (EDIT: this is the same as LB's post; hadn't seen it at that time)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <type_traits>

template< typename T1, typename T2,
          bool SAME_NESTED_TYPE = std::is_same< typename T1::ElementType,
                                                typename T2::ElementType>::value >
class combo
{
    static_assert( SAME_NESTED_TYPE,
                   "the nested type 'ElementType' must be the same for both types" ) ;
    //...
};

template< typename T1, typename T2 > class combo< T1, T2, true >
{
    // ...
};
Last edited on
Thanks, static_assert is what I want. Now my code looks like this:
1
2
3
4
5
6
7
8
9
10
#include <type_traits>

template<class T1,class T2>
class combo
{
    static_assert(std::is_same< typename T1::ElementType,
                                typename T2::ElementType>::value >, 
                    "T1::ElementType must be the same as T2::ElementType");
....
}
Ah, I was slightly confused but now think I understand. Though I still do not see why you would want the compiler to 'generate' the design of the specialization unless you planned to allow the case where the nested types were different.
Last edited on
> Now my code looks like this

Yes! We don't need that specialization at all.
Topic archived. No new replies allowed.