Determining the return type of a "common function"

Suppose I want to develop a common library that should be used with numeric types, including double and user types. The problem that I am facing now is that I do not know how to write a return type of a function template, like this one:

template<class T>
auto transmogrify(T x)
-> ???
{
    using std::abs;
    return abs(x)+2.0;
}

The using declaration does this piece of the function function template for primitive types because they do not have an associated namespace (and therefore ADL does not exist). But I want transogrify to use specialized abs functions if a custom type author provides their own abs function. I can't just use

-> decltype( abs(x)+2.0 )

because it doesn't work, say, doubles, since std :: abs is not in scope (as far as I can tell). But to write

-> decltype( std::abs(x)+2.0 )

ADL. ADL . , , abs, T, .

, , () ADL () (, std:: abs ) , .

+5
2

, use. , use . - , .

namespace transmog_detail
{
   using std::abs;

   template<class T>
   auto transmogrify(T x) -> decltype(abs(x) + 2.0)
   {
      return abs(x) + 2.0;
   }
}

// Then pull it into the current namespace, as recommended by @LucDanton.
using transmog_detail::transmogrify;

// Or if there is a reason, you can forward. 
// template<class T>
// auto transmogrify(T x)
// -> decltype(transmog_detail::transmogrify(x))
// {
//    return transmog_detail::transmogrify(x);
// }
+12
-6

All Articles