Программа С++ (несколько неожиданно, во-первых, для меня) компилируется и работает нормально, за исключением строки, прокомментированной в конце main()
, которая является ошибкой во время компиляции, если она раскоментирована.
#include <typeinfo>
#include <iostream>
struct Foo {
int x;
};
template <typename T>
void create(char *buffer)
{
std::cout << "creating " << typeid(T).name() << std::endl;
new (buffer) T();
}
template <typename T>
void destroy(char *buffer)
{
std::cout << "destroying " << typeid(T).name() << std::endl;
((T*)buffer)->~T();
}
int main(int argc, char **argv)
{
char buffer[sizeof(Foo) > sizeof(bool) ? sizeof(Foo) : sizeof(bool)];
// create/destroy Foo via template function calls
create<Foo>(buffer);
destroy<Foo>(buffer);
// now do the above explicitly...
new (buffer) Foo();
((Foo*)buffer)->~Foo();
// create/destroy bool via template function calls
create<bool>(buffer);
destroy<bool>(buffer);
// now do the above explicitly...
new (buffer) bool();
// ((bool*)buffer)->~bool(); // oops, doesn't work
return 0;
}
Я понимаю из этого, что С++ (или, по крайней мере, g++ идея С++) допускает "явный вызов деструктора" типа параметра шаблона, даже если вручную выполнение замены типа приводит к синтаксической ошибке (поскольку bool
doesn На самом деле на самом деле есть деструктор для вызова).
Чтобы быть более явным, строка:
((T*)buffer)->~T();
компилируется и работает нормально, когда T устанавливается на bool
, но делает то же самое с фактическим bool
:
((bool*)buffer)->~bool();
является синтаксической ошибкой.
Я обнаружил это поведение, поскольку я делал метапрограммирование шаблона и считаю его очень полезным, поэтому я предполагаю, что он стандартный и был добавлен специально для обработки таких случаев, как тот, который у меня выше. Кто-нибудь знает наверняка, действительно ли это так, и когда это поведение стандартизировано, если оно есть?
Кроме того, может ли кто-нибудь указать, что такое точная формулировка в стандарте, что позволяет это, и объем ситуаций, которые он разрешает? (Я не умею читать стандартизированный, поэтому мне сложно понять это.)