Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can concept checking be delayed till class instantiation in C++?

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.

like image 531
Fedor Avatar asked Sep 10 '25 15:09

Fedor


1 Answers

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.

like image 164
Yakk - Adam Nevraumont Avatar answered Sep 13 '25 03:09

Yakk - Adam Nevraumont