SFINAE не находится в игре, потому что члены типов, произведенных в вашей точке возврата MakeContainer
, не проверяются во время SFINAE с перегрузками MakeContainer
.
SFINAE происходит только в непосредственном контексте.Тела типов и функций не входят в область действия и не вызывают сбоя в замене.
template <typename T=char[7]> Container<char[7]> MakeContainer(char const (&)[7])
с этой подписью все в порядке.
После выбора создается экземпляр Container<char[7]>
и его методы.синтаксический анализ.
template <typename TPred> char[7] find_if(TPred pred); // the culprit
нет TPred
, который мог бы привести к тому, что этот find_if
был допустимым методом, поэтому ваша программа неправильно сформирована, диагностика не требуется.
Правильное исправление:
template <typename T> struct Container
{
template <typename TPred> T find_if(TPred pred); // the culprit
};
template <class T, std::size_t N> struct Container<T[N]>:
Container<std::array<T,N>>
{
using Container<std::array<T,N>>::Container;
};
конечно, Container<std::array<T,N>>
сам по себе нуждается в очень специальных find_if
и, вероятно, в конструкторах.Но, по крайней мере, это не сломается сразу.