Reputation: 21271
A common practice to speed up compilation is to only declare classes instead of giving their full definitions, e.g.
struct A;
template<typename T> struct B;
using C = B<A>;
By if one likes to use C++20 concepts in template classes then the code as follows
#include <concepts>
struct A;
template<std::destructible T> struct B;
using C = B<A>;
will result in error:
error: template constraint failure for 'template<class T> requires destructible<T> struct B'
| using C = B<A>;
Is it possible to somehow delay the moment of concept checking till B<A>
is really used/instantiated? If not, then it seems that concepts will significantly slow down compilation of some programs by forcing to include class definitions which were previously hidden.
Upvotes: 4
Views: 231
Reputation: 275510
This is how you forward declare.
struct A;
template<class T> struct B;
using C = B<A>;
keep this. In B.h
:
#include <concepts>
template<class T> struct B;
// or
template<class T> struct B
{
static_assert( std::destructible<T> );
};
template<std::destructible T>
struct B<T> {
};
specialize. Leave the base B<T>
undefined.
Now, the errors you get aren't going to be checked "early", but rather occur at a later spot. So passing T
to B<>
won't check in a SFINAE-friendly way.
But that basically is what you asked not to happen in your question.
Note that the static_assert
may, under certain readings of the standard, make your program ill-formed, no diagnostic required. Basically all specializations (including the base one) must have a valid instantiation, and pattern matching of the other specialization makes this impossible.
But in practice I think you just get an error message.
Upvotes: 3