Argument deduction constraints are similar to implicit conversion constraints, except argument deduction constraints have one or more placeholders in the trailing return type field.
A placeholder is the keyword auto
used in a template argument list within a concept requires clause.
Here is an example of an argument deduction constraint:
First we need a template type to use in our experiment. It accepts two template parameters.
template<typename T, typename U> struct Pair{};
Next, we use the true concept and put it to good use. Why will be explained later.
template<typename T>
concept bool C1() { return true; }
Here is the argument deduction concept in all its glory.
template<typename T>
concept bool C2()
{
return requires(T t)
{
{*t} -> Pair<C1&, auto>; // auto is the placeholder
};
}
Most of the concept is just a standard function concept. The interesting part is the line:
{*t} -> Pair<C1&, auto>;
Part by part, the requires expression works like this:
{*t}
, must match the trailing return type indicated by ->
.Pair<T,U>
.T
must be equivalent to C1&
. This means the type of T
must be a reference type.U
is deferred to later with auto
, also known as argument deduction.This code will pass the argument deduction constraint.
template<C2 T> void arg_deduction(T)
{}
auto *pair = new Pair<int&, double>();
arg_deduction(pair);
As long as the variable is a pointer of Pair<T,U>
, and the type T
is a reference, all is good.
Professional Software Developer, doing mostly C++. Connect with Kent on Twitter.