#include <iostream>
#include <type_traits>
template < typename T>
struct vec;
template < typename T, bool B>
struct vec_impl;
template < typename T>
struct vec_impl< T, true > {
static void add( const vec< T> & self, const T& a) {
T n( a) ;
}
} ;
template < typename T>
class vec {
friend struct vec_impl< T, true > ;
public :
virtual void add( const T& a) {
vec_impl< T, std:: is_copy_constructible < T> :: value > :: add ( * this , a) ;
}
virtual void add( T&& a) {
}
} ;
struct mov {
mov( ) = default ;
mov( const mov& ) = delete ;
mov( mov&& ) = default ;
} ;
int main( ) {
mov m;
vec< mov> v;
v.add ( std:: move ( m) ) ;
return 0 ;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4Kc3RydWN0IHZlYzsKCnRlbXBsYXRlIDx0eXBlbmFtZSBULCBib29sIEI+CnN0cnVjdCB2ZWNfaW1wbDsKCnRlbXBsYXRlIDx0eXBlbmFtZSBUPgpzdHJ1Y3QgdmVjX2ltcGw8VCwgdHJ1ZT4gewoJc3RhdGljIHZvaWQgYWRkKGNvbnN0IHZlYzxUPiYgc2VsZiwgY29uc3QgVCYgYSkgewoJCVQgbihhKTsKCX0KfTsKCnRlbXBsYXRlIDx0eXBlbmFtZSBUPgpjbGFzcyB2ZWMgewoJZnJpZW5kIHN0cnVjdCB2ZWNfaW1wbDxULCB0cnVlPjsKCQpwdWJsaWM6Cgl2aXJ0dWFsIHZvaWQgYWRkKGNvbnN0IFQmIGEpIHsKCQl2ZWNfaW1wbDxULCBzdGQ6OmlzX2NvcHlfY29uc3RydWN0aWJsZTxUPjo6dmFsdWU+OjphZGQoKnRoaXMsIGEpOwoJfQoKCXZpcnR1YWwgdm9pZCBhZGQoVCYmIGEpIHsKCQkKCX0KfTsKCnN0cnVjdCBtb3YgewoJbW92KCkgPSBkZWZhdWx0OwoJbW92KGNvbnN0IG1vdiYpID0gZGVsZXRlOwoJbW92KG1vdiYmKSA9IGRlZmF1bHQ7Cn07CgppbnQgbWFpbigpIHsKCW1vdiBtOwoJCgl2ZWM8bW92PiB2OwoJCgl2LmFkZChzdGQ6Om1vdmUobSkpOwoKCXJldHVybiAwOwp9
compilation info
prog.cpp: In instantiation of ‘void vec<T>::add(const T&) [with T = mov]’:
prog.cpp:45:1: required from here
prog.cpp:23:66: error: incomplete type ‘vec_impl<mov, false>’ used in nested name specifier
vec_impl<T, std::is_copy_constructible<T>::value>::add(*this, a);
^
stdout