c++templates

concept to check for absence of member


I want a concept that identifies when a template specialization has been performed. In other words, by default, it returns false, and only returns true if a customization has been done. I have successfully gotten this to work with the following code:

demo

template <typename T>
struct WrapperEnabled
{
    static constexpr const bool disabled = true;
};

template <typename T>
concept WrapperDisabled = WrapperEnabled<T>::disabled;

template <typename T>
concept Wrappable = !WrapperDisabled<T>;

Wrappable<T> will now be false for every data type, unless you have done this in your code:

template <>
struct WrapperEnabled<MyClass>;

As such, I can then use it in template declarations:

template<Wrappable T>
class X { ... }

Great, so far so good. My question is whether I can define the Wrappable concept directly instead of needing the intermediate WrapperDisabled concept. From my experiments, any sort of boolean logic performed on a non-existent member just causes the entire expression to resolve to false . Something like this for example:

template <typename T>
concept Wrappable = (!WrapperEnabled<T>::disabled); // Error!

Is there some way to do this?


Solution

  • Maybe you are looking for a (negated) nested requirement like this:

    template<typename T>
    concept Wrappable = !requires { requires WrapperEnabled<T>::disabled; };
    

    This is true if and only if either

    It still fails hard if WrapperEnabled<T>::disabled is well-formed, but not a constant expression.

    The requires-expression with nested requirement requires { requires X; } above behaves like checking C<T> for satisfication where C is defined as template<typename T> concept C = X;.