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.