Tengo un problema en el que me gustaría proporcionar una versión genérica de una función foo
que solo se puede aplicar cuando no existe absolutamente ninguna otra coincidencia para una invocación. ¿Cómo puedo modificar el siguiente código para que last_resort::foo
coincidan peor con derived::type
que con base::foo
? Me gustaría encontrar una solución que no implique modificar la definición de bar
y que preserve el tipo de argumento de last_resort::foo
.¿Cómo hacer que una plantilla de función tenga la menor prioridad durante la ADL?
#include <iostream>
namespace last_resort
{
template<typename T> void foo(T)
{
std::cout << "last_resort::foo" << std::endl;
}
}
template<typename T> void bar(T)
{
using last_resort::foo;
foo(T());
}
namespace unrelated
{
struct type {};
}
namespace base
{
struct type {};
void foo(type)
{
std::cout << "base::foo" << std::endl;
}
}
namespace derived
{
struct type : base::type {};
}
int main()
{
bar(unrelated::type()); // calls last_resort::foo
bar(base::type()); // calls base::foo
bar(derived::type()); // should call base::foo, but calls last_resort::foo instead
return 0;
}
Eso es cierto, pero me pregunto si hay una forma de introducir una conversión "oculta" en foo aumentándola con algunos parámetros adicionales con valores predeterminados. –
No creo que funcione. Por lo que puedo decir, lo "mejor" que puede obtener es una ambigüedad para que la compilación falle. Pero tal vez, me falta algo, también. – sellibitze
La solución parece ser decorar el tipo de retorno '' 'last_resort :: foo''' con algo como' '' disable_if_foo_exists :: type''', que usará SFINAE para comprobar si hay '' 'foo libre '' 'función. Si existe, '' 'last_resort :: foo''' se eliminaría del conjunto de sobrecarga. –