language: C++ 4.7.2 (gcc-4.7.2)
date: 768 days 16 hours ago
link:
visibility: public
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <cassert>
 
template<typename S> struct PA1 {};
template<typename S> struct PA2 {};
template<typename S> struct PB  {};
template<typename S> struct PC  {};
 
template<typename S> struct A1 { typedef PA1<S> P; };
template<typename S> struct A2 { typedef PA2<S> P; };
template<typename S> struct B  { typedef PB <S> P; };
template<typename S> struct C  { typedef PC <S> P; };
 
template<typename S, template<typename> class T> char fn(typename T<S>::P);
 
template<typename S, template<typename> class T> char fn(typename T<S>::P)
{
    return 'a';
}
 
template<typename S> char fn(typename B<S>::P) {   return 'b';  }
template<typename S> char fn(typename C<S>::P) {   return 'c';  }
 
template<class S, template<typename> class T>
struct call
{
    static char fn(typename T<S>::P &p)
    {
         return ::fn<S,T>(p);
    }
};
 
template<class S>
struct call<S,B>
{
    static char fn(typename B<S>::P &p)
    {
         return ::fn<S>(p);
    }
};
 
template<class S>
struct call<S,C>
{
    static char fn(typename C<S>::P &p)
    {
         return ::fn<S>(p);
    }
};
 
int main()
{
    assert(1);
    PA1<int> pa1;
    PA2<int> pa2;
    PB<int>  pb;
    PC<int>  pc;
 
    assert( (call<int, A1>::fn(pa1)) == 'a' );
    assert( (call<int, A2>::fn(pa2)) == 'a' );
 
    assert( (call<int, B>::fn(pb)) == 'b' );
    assert( (call<int, C>::fn(pc)) == 'c' );
}