The standard rules:
[expr.prim.id.unqual]/nt:unqualified-id:
unqualified-id: ...
- ~ type-name
- ~ decltype-specifier ...
[dcl.type.simple]/nt:type-name:
type-name:
- class-name
- enum-name
- typedef-name
A name of scalar type isn't a type-name, so the standard disallows the use of it.
It disallows std::destroy_at
from being implemented as p->~T()
because T
may be substituted with a scalar type.
However, the following code compiles:
template <typename T>
void destroy_at(T* p)
{
p->~T();
}
int main()
{
int i = 0;
destroy_at(&i);
}
I don't know why.
What's the point of disallowing such use?