Search code examples
c++c++14template-meta-programmingargument-dependent-lookuptrailing-return-type

Name lookup issue in trailing return type


The following example illustrates my question:

#include <iostream>
#include <string>

template <typename T>
auto func(const T& x) -> decltype(to_string(x)) {
  using std::to_string;
  return to_string(x);
}

int main() {
  std::cout << func(1);
}

I don't want to import std::to_string into global namespace, not do I want to use -> decltype(std::to_string(x)) as doing this disables ADL. Obviously, you can't put using std::to_string within decltype. So, how should I do it?


Solution

  • Defer to another namespace;

    namespace activate_adl {
      using std::to_string;
      template <typename T>
      auto func(const T& x) -> decltype(to_string(x)) {
        return to_string(x);
      }
    }
    
    template <typename T>
    auto func(const T& x) -> decltype(activate_adl::func(x)) {
      return activate_dl:: func(x);
    }
    

    This allows the ADL to still be done, but doesn't pollute you global namespace.

    Having hit this issue a few times with some std related functions and ADL, I've found the deferred namespace (well named) is be suitable alternatives.