TL;DR: Require users to specify all necessary concepts in template. This is, of course, incompatible change, so it should be implemented using epochs (
http://wg21.link/P1881 ). This is what templates should be right from the beginning.
You seem to be talking about something basically the same as what used to be called "definition checking." The idea would be that if we had some way to specify that a type was "addable," then we could write
template<Addable T> auto add(T x, T y) { return x + y; }
The problem with this in C++2a is that C++2a Concepts are "Concepts Lite"; they do not, and fundamentally cannot, support definition checking. Consider what would happen if you wrote the following C++2a code:
template<class T>
concept Addable = requires(const T& t) {
{ t + t };
};
Without definition checking, our "add" function template above compiles fine (because you don't have to do any checking on the template itself), and you can even instantiate it with common-law-addable types, so that we can form `add<int>` and `add<std::string>`.
But if we blindly added definition checking to C++2a Concepts Lite, then our code would no longer compile! Definition checking means that we don't check just when we instantiate the template; the compiler would actually check the definition of the template itself and inform us that the template uses functionality that is not reflected in the Addable concept.
Proof by example:
struct Evil1 {
int operator+(const Evil1&) const;
int operator+(Evil1&) = delete;
};
static_assert(Addable<Evil1>); auto failure1 = &add<Evil1>;
Proof by a different example:
struct Evil2 {
Evil2& operator+(const Evil2&) const;
Evil2(Evil2&&) = default;
};
static_assert(Addable<Evil2>); auto failure2 = &add<Evil2>;