Вторая перегрузка выполняет условие «Иначе» в определении, заданном в cppreference :
1) Если T - это тип функции, который не имеет cv- илиref-определитель или тип объекта, предоставляет тип-члена-члена typedef, который является T &. Если T является rvalue ссылкой на некоторый тип U, тогда тип - U &. В противном случае типом является T.
Рассмотрим, например:
using T = void() const; // Function type with const qualifier
using U = add_lvalue_reference<T>::type;
В соответствии с определением у нас должно быть U == T
, но если у нас нет второй перегрузки шаблона, тогда этот код вызовет ошибку во время компиляции:
Невозможно сформировать ссылки на cv- или ref-квалифицированные типы функций, и поэтому первая перегрузка шаблона try_add_lvalue_reference
исключена SFINAE.
Если есть только эта перегрузка, вызов detail::try_add_lvalue_reference<T>(0)
вызывает сбой, потому что нет жизнеспособной перегрузки.
Вторая перегрузка не пытается сформировать ссылку на квалифицированный const тип функции ипоэтому всегда жизнеспособен и будет выбран, если первый не вернет, возвращая сам тип.
Параметры int
и ...
гарантируют, что обе перегрузки могут быть вызваны с аргументом int
и...
имеет дополнительное преимущество: он всегда имеет более низкий приоритет при разрешении перегрузки. Поэтому, если обе перегрузки шаблона являются жизнеспособными, будет выбран первый, чтобы обеспечить тип с добавленной ссылкой lvalue, где это возможно.