SFINAE в стиле C ++ 11 и видимость функций при создании шаблона

Я не уверен, имеет ли это какое-либо отношение к sfinae или что-то, что имеет отношение к какой-либо шаблонной функции. Я пытаюсь использовать sfinae для включения / выключения функции-члена на основе существования соответствующей свободной функции, которая, в свою очередь, включается / отключается на основе существования функции-члена в другом типе, все с использованием описанного методаВот:

struct S;

template <typename T>
inline auto f(S& s, T const& t)
   -> decltype(t.f(s), void())
{
   t.f(s);
}

struct S
{
    template <typename T>
    auto f(T const& t)
        -> decltype(f(*this, t), void())
    {
        f(*this, t); // <------------------------------------------- HERE
    }
};

struct pass
{
    void f(S&) const
    {
        //...
    }
};

struct fail
{
};

int main()
{
    S s;
    s.f(pass()); // should compile fine
    //s.f(fail()); // should fail to compile due to absence of f from S
    return 0;
}

однако gcc 4.7.1 дает мне это в строке, отмеченной стрелкой:

error: no matching function for call to 'S::f(S&, const pass&)'
note: candidate is:
note: template decltype ((f((* this), t), void())) S::f(const T&)
note: template argument deduction/substitution failed:
note: candidate expects 1 argument, 2 provided

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

Почему это так и что мне делать, чтобы это сделать?

И почему нет ошибок на две строки выше, гдеf используется в decltype аналогичным образом?

UPDATE

Как @ n.m. Сказано, что функции-члены полностью без теней, даже если их сигнатуры различны, так что здесь есть обходной путь, который не нарушает ADL дляf (в отличие от полной квалификации имени, предложенной @ n.m.). Сделай свободную функцию (f_dispatcher) где-то никто не будет смотреть (detail) и полностью уточните его название внутриS::f, В этой функции вызов бесплатныйf и пусть ADL позаботится об этом, вот так:

struct S;

template <typename T>
inline auto f(S& s, T const& t)
    -> decltype(t.f(s), void())
{
    t.f(s);
}

namespace detail
{
    template <typename T>
    inline auto f_dispatcher(S& s, T const& t)
        -> decltype(f(s, t), void())
    {
        f(s, t);
    }
}

struct S
{
    template <typename T>
    auto f(T const& t)
        -> decltype(detail::f_dispatcher(*this, t), void())
    {
        detail::f_dispatcher(*this, t);
    }
};

struct pass
{
    void f(S&) const
    {
        //...
    }
};

struct fail
{
};

int main()
{
    S s;
    s.f(pass()); // compiles fine
    //s.f(fail()); // fails to compile due to absence of f from S
    return 0;
}

Ответы на вопрос(1)

Ваш ответ на вопрос