#include<iostream>
#include<type_traits>
struct A{ } ;
struct B{ } ;
struct C{ } ;
template < typename ... Args >
struct Convert;
template < typename T>
struct Convert< T,T> {
static int param( ) { return 0 ; }
} ;
template < typename T, typename U>
struct Convert< T,U> {
static decltype( - Convert< U,T> :: param ( ) ) param( ) { return - Convert< U,T> :: param ( ) ; }
} ;
template <>
struct Convert< A,B> {
static int param( ) { return 42 ; }
} ;
template <>
struct Convert< A,C> {
static int param( ) { return 43 ; }
} ;
template <>
struct Convert< B,C> {
static int param( ) { return 44 ; }
} ;
int main( )
{
std:: cout << Convert< A,B> :: param ( ) << std:: endl ;
std:: cout << Convert< B,A> :: param ( ) << std:: endl ;
std:: cout << Convert< A,C> :: param ( ) << std:: endl ;
std:: cout << Convert< C,A> :: param ( ) << std:: endl ;
std:: cout << Convert< B,C> :: param ( ) << std:: endl ;
std:: cout << Convert< C,B> :: param ( ) << std:: endl ;
Convert< int ,double > :: param ( ) ;
}
CgojaW5jbHVkZTxpb3N0cmVhbT4KI2luY2x1ZGU8dHlwZV90cmFpdHM+CgpzdHJ1Y3QgQXt9OwpzdHJ1Y3QgQnt9OwpzdHJ1Y3QgQ3t9OwoKCgp0ZW1wbGF0ZSA8dHlwZW5hbWUgLi4uIEFyZ3M+CnN0cnVjdCBDb252ZXJ0OwoKdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CnN0cnVjdCBDb252ZXJ0PFQsVD4gewogICAgCiAgICBzdGF0aWMgaW50IHBhcmFtKCkgeyByZXR1cm4gMDsgfQp9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHR5cGVuYW1lIFU+CnN0cnVjdCBDb252ZXJ0PFQsVT4gewogICAgCiAgICBzdGF0aWMgZGVjbHR5cGUoLUNvbnZlcnQ8VSxUPjo6cGFyYW0oKSkgcGFyYW0oKSB7IHJldHVybiAtQ29udmVydDxVLFQ+OjpwYXJhbSgpOyB9Cn07Cgp0ZW1wbGF0ZSA8PgpzdHJ1Y3QgQ29udmVydDxBLEI+IHsKICAgIHN0YXRpYyBpbnQgcGFyYW0oKSB7IHJldHVybiA0MjsgfQp9OwoKdGVtcGxhdGUgPD4Kc3RydWN0IENvbnZlcnQ8QSxDPiB7CiAgICBzdGF0aWMgaW50IHBhcmFtKCkgeyByZXR1cm4gNDM7IH0KfTsKCnRlbXBsYXRlIDw+CnN0cnVjdCBDb252ZXJ0PEIsQz4gewogICAgc3RhdGljIGludCBwYXJhbSgpIHsgcmV0dXJuIDQ0OyB9Cn07CgppbnQgbWFpbigpCnsKICAgIHN0ZDo6Y291dDw8Q29udmVydDxBLEI+OjpwYXJhbSgpPDxzdGQ6OmVuZGw7CiAgICBzdGQ6OmNvdXQ8PENvbnZlcnQ8QixBPjo6cGFyYW0oKTw8c3RkOjplbmRsOwogICAgc3RkOjpjb3V0PDxDb252ZXJ0PEEsQz46OnBhcmFtKCk8PHN0ZDo6ZW5kbDsKICAgIHN0ZDo6Y291dDw8Q29udmVydDxDLEE+OjpwYXJhbSgpPDxzdGQ6OmVuZGw7CiAgICBzdGQ6OmNvdXQ8PENvbnZlcnQ8QixDPjo6cGFyYW0oKTw8c3RkOjplbmRsOwogICAgc3RkOjpjb3V0PDxDb252ZXJ0PEMsQj46OnBhcmFtKCk8PHN0ZDo6ZW5kbDsKCiAgICBDb252ZXJ0PGludCxkb3VibGU+OjpwYXJhbSgpOwp9
compilation info
prog.cpp: In instantiation of ‘struct Convert<double, int>’:
prog.cpp:24:42: required from ‘struct Convert<int, double>’
prog.cpp:51:24: required from here
prog.cpp:24:42: error: incomplete type ‘Convert<int, double>’ used in nested name specifier
static decltype(-Convert<U,T>::param()) param() { return -Convert<U,T>::param(); }
^
prog.cpp: In instantiation of ‘struct Convert<int, double>’:
prog.cpp:51:24: required from here
prog.cpp:24:42: error: ‘param’ is not a member of ‘Convert<double, int>’
prog.cpp: In function ‘int main()’:
prog.cpp:51:5: error: ‘param’ is not a member of ‘Convert<int, double>’
Convert<int,double>::param();
^
stdout