Integer version of c++ standard library midpoint
Naming things
The variable names are not very clear. I assume the _2x stands for &quot;2's complement&quot; instead for &quot;times 2&quot;, but for someone who doesn't know the context, it will be hard to follow. I'm not sure what the best way to name them is though, but as shown below you can avoid the issue altogether.
Don't use a template parameter for a derived type
If you make Unsigned a template parameter, it means someone can override it to something nonsensical. If you want to have a named type that is a derivative of another type, use using inside the function body:
template&lt;typename Integer&gt;
Integer midpoint(Integer a, Integer b)
{
    using Unsigned = std::make_unsigned_t&lt;Integer&gt;;
    ...
}

Simplifying the code
Most of the temporary variables can be removed. I would keep the variable diff, as it is the most important one where the casts are essential, and since it is used twice:
template&lt;typename Integer&gt;
Integer midpoint(Integer a, Integer b)
{
    using Unsigned = std::make_unsigned_t&lt;Integer&gt;;
    Unsigned diff = Unsigned(b) - Unsigned(a);
    return a + (b &lt; a ? -Integer(Unsigned(-diff) / 2) : Integer(diff / 2));
}

The return expression is still reasonably short, and I don't think any information was lost. Adding some comments explaining why the casts are necessary would be helpful though.