Применяется ли SFINAE к функциональным органам?

У меня есть следующий пример кода:

class Serializable {};

class MyData : public Serializable {};

void GetData( Serializable& ) {}

template<typename T>
void GetData( T& data )
{
std::istringstream s{"test"};
s >> data;
}

int main()
{
MyData d;
GetData(d);
}

(Живой Образец)

Основываясь на правилах разрешения перегрузки, предпочтительна не шаблонная версия, потому что базовый класс имеет тип Serializable, Тем не менее, я ожидаю, что SFINAE сработает, когда в версии шаблона возникнут ошибки, когда он создается для разрешения перегрузки (потому что, если для типа не определен оператор >>, это не должно учитываться).

Почему по-прежнему происходит сбой, даже если шаблон не будет использоваться?

2

Решение

Исходя из правил разрешения перегрузки, не шаблонная версия должна быть
предпочтительнее, потому что базовый класс имеет тип Serializable,

Не совсем. [Over.match.best]:

Учитывая эти определения, жизнеспособная функция F1 определяется как
лучшая функция, чем другая жизнеспособная функция F2 если для всех аргументов
i, ICSi (F1) не хуже последовательности преобразования, чем ICSi (F2), а затем

  • для некоторого аргумента j ICSj (F1) является лучшей последовательностью преобразования, чем ICSj (F2), или, если не это,
  • […]
  • F1 не специализация шаблона функции и F2 это специализация шаблона функции […]

Это означает, что только если выводимая специализация шаблона функции требует преобразования, которое не лучше, чем преобразование, которое требует нормальная функция, применяется ваше правило.
И привязка d в Serializable& является худшим преобразованием, чем привязка d к MyData& (это тип параметра специализации), [over.ics.ref]:

Когда параметр ссылочного типа привязывается напрямую (8.5.3) к
выражение аргумента, неявная последовательность преобразования является тождеством
преобразование, если выражение аргумента не имеет тип, который является
производный класс типа параметра, в этом случае неявный
последовательность преобразования представляет собой преобразование из базы в производную (13.3.3.1).

Тем не менее, я ожидаю, что SFINAE начнет действовать, когда в
версия шаблона, когда он создается для разрешения перегрузки
(потому что если оператор >> не определен для типа, он не должен
быть принятым во внимание).

SFINAE не распространяется на содержание шаблона функции. [Temp.deduct] / 8:

Только недопустимые типы и выражения в непосредственном контексте
тип функции и типы параметров шаблона
может привести к
сбой удержания.

Следовательно, выведенная специализация шаблона функции действительно выбрана и вызывает ошибку компилятора при создании его определения.

4

Другие решения


По вопросам рекламы [email protected]