Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overload/specialization of a concept

Is there a way to overload/specialize concepts like templates?

Consider the following pretty simple case where we just want to flag certain Types as 'simple':

// overload/specialization for MyClass - WOULD BE NICE - BUT FAILS

template <typename T>
concept simple = false;

class MyClass;
template <>
concept simple<MyClass> = true;

// workaround, rather verbose - SUCCEEDS

template <typename T>
concept simple = Info<T>::is_simple;

template <typename T>
struct Info
{
    static inline constexpr bool is_simple = false;
};    

class MyClass;
template <>
struct Info<MyClass>
{
    static inline constexpr bool is_simple = true;
};

Is there a simpler way to achieve this?

like image 505
non-user38741 Avatar asked Nov 15 '25 18:11

non-user38741


1 Answers

Is there a way to overload/specialize concepts like templates?

No. You cannot overload or specialize concepts. Concepts are what they are. This is by design.

If I have a concept Frobnable, that concept always means what it means. The fundamental issue with template specializations is that that the specializations don't actually have to have anything to do with the primary. We just like... ensure that they are, for sanity's sake. Except when we don't, like vector<bool> doesn't really have the same interface as vector<T> for all other T.

But if Frobnable<T> meant something just totally different from Frobnable<T*> (or insert your choice of specialization here), then you couldn't possibly come up with any rules for what concept subsumption would mean - or really reason about concepts much at all.

Concepts are much more structured than templates.


So to go back to your question of how do

[...] we just want to flag certain Types as 'simple':

You should use a variable template for this, and then possibly have a concept just refer to that variable template.

template <typename T>
inline constexpr bool is_simple = false;

template <>
inline constexpr bool is_simple<MyClass> = true;

template <typename T>
concept simple = is_simple<T>::value;

Or don't even bother with the concept and just use the variable template directly in a requires clause.

like image 177
Barry Avatar answered Nov 18 '25 08:11

Barry