Вы можете использовать признаки типа шаблона в качестве обходного пути для извлечения такой информации из определенных типов.Это не может различить, было ли что-то явно удалено или неявно, но вы точно знаете, что если вы не сделали это явно, например,
#include <iostream>
#include <type_traits>
struct A {
A(const A&) = delete;
};
int main() {
std::cout << std::boolalpha << std::is_trivially_default_constructible_v<A> << '\n';
std::cout << std::boolalpha << std::is_copy_assignable_v<A> << '\n';
std::cout << std::boolalpha << std::is_trivially_move_constructible_v<A> << '\n';
}
приведет к false, true, false
, например, тривиальный конструктор по умолчаниюнеявно удаляется, когда конструктор копирования явно удаляется.
Редактировать: Вот пример, который проходит через иерархию классов и находит базовый класс, который нарушает определенную черту:
#include <iostream>
#include <type_traits>
#include <typeinfo>
struct A {
A(const A&) = delete;
A(A&&) noexcept { }
};
struct B : A {
using base_type = A;
B(B&& b) : A(std::move(b)) { }
};
struct C : B {
using base_type = B;
};
struct D : C {
using base_type = C;
};
template <typename T, bool = std::is_nothrow_move_constructible_v<typename T::base_type>>
struct check { };
template <typename T>
struct check<T, false> : check<typename T::base_type> { };
template <typename T>
struct check<T, true> {
using result_t = T;
};
int main() {
std::cout << typeid(check<D>::result_t).name() << '\n';
}
ОттудаВы можете сами придумать, как его улучшить и обобщить.