Given the following example:
#include <type_traits>
#include <vector>
#include <string>
template <typename T, typename = void>
struct has_name: std::false_type {};
template <typename T>
struct has_name<T, decltype(std::declval<T>().name, void())>: std::true_type {};
template <typename T>
struct MyContainer {
static_assert(has_name<T>::value);
std::vector<T> elements;
};
struct Parent;
struct Child;
struct Parent {
std::string name;
MyContainer<Child> children;
};
struct Child {
std::string name;
MyContainer<Parent> parents;
};
This does not compile because Child in MyContainer<Child> inside Parent is an incomplete type, so the static_assert that checks for a name member fails. How can I perform assertions about incomplete types or if anything here is bad practice, what should I do instead?
(I am aware that the example is a bit contrived, I tried to reduce my real world scenario to a minimum.)