Home > Enterprise >  Is there any way to pass C concepts themselves?
Is there any way to pass C concepts themselves?

Time:02-05

template<class S>
using Floating1 = std::is_floating_point<S>;
template<class S>
concept Floating2 = std::is_floating_point_v<S>;

You can pass Floating1...

template<template<class...> class F> struct TType {
    template<class... S> using type = F<S...>;
};
using X = TType<Floating1>;
//...
template<class S> using Y = typename X::template type<S>;

So what about Floating2? You can call a function that distinguishes a Floating2 if you know that's what you're looking for, just like instantiating Floating1<S>; but how do you pass Floating2 like TType<Floating1>?

I highly suspect that it can't be done, any more than you can pass class or auto.

As a possible use case, functions like std::invoke have variants that let you specify a return type. It would be great if that return type could be a constrained auto. Can any function, template, etc. accept a concept, outside of concepts/requirements themselves?

Or you could write two helper functions, one using the concept and one not, for each and every concept you want to consider. There has to be a better way.

CodePudding user response:

No, concepts can't be passed as template (or any other kind of) arguments.

As a possible use case, functions like std::invoke have variants that let you specify a return type. It would be great if that return type could be a constrained auto. Can any function, template, etc. accept a concept, outside of concepts/requirements themselves?

The caller of std::invoke can already achieve the exact same behavior that this would have at the call site, i.e.

SomeConcept auto ret = std::invoke(/*...*/);

This will produce an error if the return value doesn't satisfy SomeConcept. That's all a constraints on a return type of std::invoke would do as well.

I suspect this wasn't considered as a feature because there aren't any or many use cases that would actually profit over the current situation.

  • Related