Ответ 1
Да. Из [temp.constr.expr], формулировка N4641:
Ограничение выражения - это ограничение, которое указывает требование на формирование выражения
E
путем замены аргументов шаблона. Ограничение выражения выполняется, если подстановка сE
не сработала. В пределах ограничения выраженияE
является неоцененным операндом (пункт 5).
Поэтому использование declval
должно быть в порядке.
В качестве альтернативы вы можете просто создавать объекты типов, которые вам нужны, поскольку в контексте требований мы на самом деле ничего не строим:
template<typename T>
concept bool SomeConcept = requires(T a, int i) {
{ a.someFunction(std::move(i)) } -> int;
};