#include <new>
#include <utility>
#include <type_traits>
struct A
{
} ;
struct B
{
int i;
} ;
template < typename T, typename U, typename ... Args >
T* construct( U ptr, Args&& ... args )
{
static_assert( std:: is_same < U, void * > :: value or std:: is_same < U, char * > :: value , "must be void* or char*" ) ;
return :: new ( ptr) T( std:: forward < Args> ( args) ...) ;
}
int main( )
{
A a;
alignas( B) char area[ sizeof ( B) ] ;
void * ptr = area;
construct< B> ( & a) ; // fails at compile time
construct< B> ( & area[ 0 ] ) ;
construct< B> ( ptr) ;
}
I2luY2x1ZGUgPG5ldz4KI2luY2x1ZGUgPHV0aWxpdHk+CiNpbmNsdWRlIDx0eXBlX3RyYWl0cz4KCnN0cnVjdCBBCnsKCn07CgpzdHJ1Y3QgQgp7CglpbnQgaTsKfTsKCnRlbXBsYXRlPHR5cGVuYW1lIFQsIHR5cGVuYW1lIFUsIHR5cGVuYW1lLi4uIEFyZ3M+ClQqIGNvbnN0cnVjdChVIHB0ciwgQXJncyYmLi4uIGFyZ3MpCnsKCXN0YXRpY19hc3NlcnQoc3RkOjppc19zYW1lPFUsIHZvaWQqPjo6dmFsdWUgb3Igc3RkOjppc19zYW1lPFUsIGNoYXIqPjo6dmFsdWUsICJtdXN0IGJlIHZvaWQqIG9yIGNoYXIqIik7CglyZXR1cm4gOjpuZXcocHRyKSBUKHN0ZDo6Zm9yd2FyZDxBcmdzPihhcmdzKS4uLik7Cn0KCmludCBtYWluKCkKewoJQSBhOwoJYWxpZ25hcyhCKSBjaGFyIGFyZWFbc2l6ZW9mKEIpXTsKCXZvaWQqIHB0ciA9IGFyZWE7Cgljb25zdHJ1Y3Q8Qj4oJmEpOyAvLyBmYWlscyBhdCBjb21waWxlIHRpbWUKCWNvbnN0cnVjdDxCPigmYXJlYVswXSk7Cgljb25zdHJ1Y3Q8Qj4ocHRyKTsKfQ==
compilation info
prog.cpp: In instantiation of 'T* construct(U, Args&& ...) [with T = B; U = A*; Args = {}]':
prog.cpp:27:17: required from here
prog.cpp:18:2: error: static assertion failed: must be void* or char*
static_assert(std::is_same<U, void*>::value or std::is_same<U, char*>::value, "must be void* or char*");
^
stdout