Pregunta

Suppose, I want to develop a generic library which should be usable with number-like types including double and user-defined types. The problem, I'm facing right now is that I don't know how to write the return type of a function template much like this one:

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

The using declaration makes this function template's body work for primitive types because these don't have an associated namespace (and hence, there is no ADL). But I want transmogrify to use specialized abs functions in case the author of a user-defined type provides his own abs function. I can't simply use

-> decltype( abs(x)+2.0 )

because this would not work for, say, doubles since std::abs is not in scope (as far as I can tell). But writing

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

would disable ADL. But disabling ADL is not an option. Also, the value returned by a specialized abs function might not be of type T but some other type.

Any ideas on how to solve the return type issue while (a) keeping ADL and (b) falling back on some default function (like std::abs in this case) for types that don't provide a specialized abs.

¿Fue útil?

Solución

Use a separate namespace, where you can put the using clause. This prevents the namespace pollution, since the using clause only applies to that namespace. I would recommend naming it something unique, so you don't accidentally spread it around.

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);
// }

Otros consejos

The above answers are good, but the simoplest way i can think of is to use the typeinfo header. it was specifically designed to determine types and constructors of objects.

see here: http://www.cplusplus.com/reference/std/typeinfo/type_info/

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top