I'm forward declaring a type and providing its definition later down the line. Once it has been fully defined it is expected to meet some requirements, and to be a suitable template argument. However, when pairing incomplete types with C++20 concepts I run into problems.
The following compiles without a hitch using GCC 13.2.0:
#include <concepts>
template <class T>
class class_without_constrained_template {};
struct A;
struct B;
struct B { class_without_constrained_template<A> var; };
struct A {};
int main() {
return 0;
};
If I try to formalize the requirements using C++20 concepts compilation fails, and the compiler complains that A is not std::destructible:
#include <concepts>
template <std::destructible T>
class class_with_constrained_template {};
struct A;
struct B;
struct B { class_with_constrained_template<A> var; };
struct A {};
int main() {
return 0;
};
I realize that at the time of defining B, A is an incomplete type that does not fulfill the requirements. However, it would fulfill them by the time you were instantiating it. I have found this related question, but the proposed solution does not seem to work when class_with_constrained_template is used as a member variable. The following fails to compile.
#include <concepts>
template <class T>
class class_with_constrained_template {
static_assert( std::destructible<T> );
};
template <std::destructible T>
class class_with_constrained_template<T> {};
struct A;
struct B;
struct B { class_with_constrained_template<A> _; };
struct A {};
int main() {
return 0;
};
In the above snippet, when is static_assert evaluated, and why does it evaluate to false? Is it possible to use C++20 concepts in this scenario? If so, how?
No. Thats not right.
Bis a class. It is not a template. It is nothing that gets instantiation later. You define it and thats it. In the Q&A you link theBis a template that is instantiated later only when the needed type is complete.If you make
Ba template, the answer from the other question applies:Live Demo