Template partial specialization

May 15, 2013 at 12:32pm
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?
May 15, 2013 at 12:50pm
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
{
    ...
};

May 15, 2013 at 12:53pm
I don't mean that, T1 T2 can be different, but their ElementType should match
May 15, 2013 at 1:14pm
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 >
{
    // ...
};
May 15, 2013 at 1:35pm
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?
May 15, 2013 at 1:42pm
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 May 15, 2013 at 1:45pm
May 15, 2013 at 1:51pm
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 May 15, 2013 at 1:54pm
May 15, 2013 at 1:55pm
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");
....
}
May 15, 2013 at 1:57pm
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 May 15, 2013 at 2:02pm
May 15, 2013 at 1:58pm
> Now my code looks like this

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