When you are working with templates and with decltype
you often need an instance of a certain type even though you do not have any the moment. In this case, std::declval<T>()
is incredibly useful. This creates an imaginary instance of the type T
.
Is there a something similar for concepts? i.e. a function which would create and imaginary type for a concept.
Let me give you an example(a bit contrived but should serve the purpose):
Let's define a concept Incrementable
template <typename T>
concept Incrementable = requires(T t){
{ ++t } -> T;
};
Now I would like to have a concept which tests if an object has the operator operator()
which can accept Incrementable
. In my imaginary syntax I would write something like this:
template <typename F, typename T = declval<Incrementable>>
concept OperatesOnIncrementable = requires(F f, T t){
{ f(t) } -> T;
}
There the declval
in typename T = declval<Incrementable>
would create an imaginary type T
which is not really a concrete type but for all intents and purposes behaves like a type which satisfies Incrementable
.
Is there a mechanism in the upcoming standard to allow for this? I would find this incredibly useful.
Edit: Some time ago I have asked a similar question if this can be done with boost::hana
.
Edit: Why is this useful? For example if you want to write a function which composes two functions
template <typename F, typename G>
auto compose(F f, G g) {
return [f, g](Incrementable auto x) { return f(g(x)); };
}
I want to get an error when I try to compose two functions which cannot be composed. Without constraining the types F
and G
I get error only when I try to call the composed function.