Я работаю над инструментом, основанным на AST clang, и мне любопытно узнать, почему clang работает таким образом.
Вот мой вклад. У меня есть очень простой класс, который определяется следующим образом:
class Foo {
int foo();
};
Затем в моем RecursiveASTVisitor у меня есть код, который выглядит так:
bool MyASTVisitor::VisitCXXRecordDecl(clang::CXXRecordDecl *D) {
for (auto const & method : D->methods()) {
llvm::outs() << method->getQualifiedNameAsString() << "(";
for (auto const & param : method->params())
llvm::outs() << param->getType().getAsString() << ", ";
llvm::outs() << ")";
if (method->isImplicit())
llvm::outs() << " [implicit]";
llvm::outs() << "\n";
}
return true;
}
Все, что он делает, это выдает список методов, определенных во всех посещаемых классах. Результат для этого, как мы и ожидали:
Foo::foo()
Теперь давайте внесем небольшое изменение в наш класс Foo. Сделаем метод foo() виртуальным:
class Foo {
virtual int foo();
};
Теперь мой вывод меняется:
Foo::foo()
Foo::operator=(const class Foo &, ) [implicit]
Foo::~Foo() [implicit]
Мой вопрос: почему добавление виртуального метода в класс приводит к тому, что clang создает неявный оператор присваивания и деструктор? Если я добавлю --std=c++11, он также создаст неявный оператор присваивания перемещения. Является ли это деталью реализации clang или частью стандарта С++?