SFINAE: verificando a existência de uma função é interrompida quando a sobrecarga é movida para outros namespaces

Quero verificar a existência de uma função em um espaço de nome específico usando SFINAE. eu encontreiSFINAE para testar uma função livre de outro espaço para nome que faz o trabalho, mas há algumas coisas que eu não entendo.

Atualmente eu tenho esse código de trabalho, diretamente da pergunta vinculada:

// switch to 0 to test the other case
#define ENABLE_FOO_BAR 1

namespace foo {
  #if ENABLE_FOO_BAR
    int bar();
  #endif
}

namespace detail_overload {
  template<typename... Args> void bar(Args&&...);
}
namespace detail {
  using namespace detail_overload;
  using namespace foo;
  template<typename T> decltype(bar()) test(T);
  template<typename> void test(...);
}
static constexpr bool has_foo_bar = std::is_same<decltype(detail::test<int>(0)), int>::value;

static_assert(has_foo_bar == ENABLE_FOO_BAR, "something went wrong");

(aENABLE_FOO_BAR macro é apenas para fins de teste, no meu código real não tenho essa macro disponível, caso contrário eu não estaria usando SFINAE)

No entanto, assim que eu colocodetail_overload::bar() em qualquer outro espaço de nome (ajustando ousing diretiva, conforme necessário), a detecção é interrompida silenciosamente e osstatic_assert entra em açãoquandofoo::bar() existe. Só funciona quando o "manequim"bar() sobrecarga está diretamente no espaço para nome global, ou parte do::detail_overload namespace (observe o global:: escopo).

// breaks
namespace feature_test {
  namespace detail_overload {
    template<typename... Args> void bar(Args&&...);
  }
  namespace detail {
    using namespace detail_overload;
    using namespace foo;
    //...

// breaks
namespace feature_test {
  template<typename... Args> void bar(Args&&...);
  namespace detail {
    using namespace foo;
    //...

// breaks
namespace detail {
  namespace detail_overload {
    template<typename... Args> void bar(Args&&...);
  }
  using namespace detail_overload;
  using namespace foo;
  //...

// works
template<typename... Args> void bar(Args&&...);
namespace feature_test {
  namespace detail {
    using namespace foo;
    //...

// works
namespace detail_overload {
  template<typename... Args> void bar(Args&&...);
}
namespace feature_test {
  namespace detail {
    using namespace detail_overload;
    using namespace foo;
    //...

Percebo que esse é o mesmo problema da pergunta a que vinculei e, como mencionado, já tenho uma solução funcional, mas o que não foi abordado é queporqueprecisamente isso acontece?

Como uma questão paralela, existe alguma maneira de obter a detecção correta de SFINAE sem poluir o namespace global combar() ou umdetail_overload namespace? Como você pode adivinhar nos exemplos que não funcionam, eu gostaria de agrupar tudo em um únicofeature_test namespace.

questionAnswers(2)

yourAnswerToTheQuestion