Компилятор не может вывести Func
из вашего второго конструктора, поэтому вам нужно указать ему, как определить параметр класса Func
, когда первый конструктор недопустим. Вы можете сделать это, добавив руководство по выводам:
template<typename T, typename Step, std::enable_if_t<!std::is_invocable_r_v<T, Step, const T &>, int> = 0>
StepRange(T, T, Step) -> StepRange<T, std::function<T(const T&)>>;
Это выведет Func
в std::function<T(const T&)>
всякий раз, когда отключен первый конструктор.
Или, если вы действительно хотите только Второй конструктор, который будет использоваться, если типы всех трех аргументов совпадают, вместо этого вы можете написать
template<typename T>
StepRange(T, T, T) -> StepRange<T, std::function<T(const T&)>>;
Конечно, в любом случае нужно рассмотреть некоторые крайние случаи.