Estoy usando una biblioteca C ++ ( strf ) que, en algún lugar dentro de ella, tiene el siguiente código:
namespace strf {
template <typename ForwardIt>
inline auto range(ForwardIt begin, ForwardIt end) { /* ... */ }
template <typename Range, typename CharT>
inline auto range(const Range& range, const CharT* sep) { /* ... */ }
}
Ahora, quiero usar strf::range<const char*>(some_char_ptr, some_char_ptr + some_length)
en mi código. Pero si lo hago, me sale el siguiente error (con NVCC de CUDA 10.1):
error: more than one instance of overloaded function "strf::range" matches the argument list:
function template "auto strf::range(ForwardIt, ForwardIt)"
function template "auto strf::range(const Range &, const CharT *)"
argument types are: (util::constexpr_string::const_iterator, util::constexpr_string::const_iterator)
El código de la biblioteca probablemente se puede cambiar para evitar esto (por ejemplo, usando:
inline auto range(const typename std::enable_if<not std::is_pointer<typename std::remove_cv<Range>::type>::value, Range &>::type range, const CharT* sep)
para asegurarse de Range
que no sea un puntero); pero no puedo hacer ese cambio en este momento. En cambio, quiero indicar de alguna manera al compilador que realmente realmente quiero tener solo un argumento de plantilla, no uno especificado y otro deducido.
¿Puedo hacer eso?
Agradecería respuestas para C ++ 11 y C ++ 14; Las respuestas de C ++ 17 que involucran guías de deducción son menos relevantes, pero si tiene una, publíquela (para futuras versiones de NVCC ...)
Actualización: la biblioteca strf en sí misma se ha actualizado para sortear esta situación, pero la pregunta se presenta como se le preguntó.
char*
pero no es uno, ¿no es una solución?Respuestas:
Luego llame en
range1
lugar destrf::range
.range1_ptr<T>(...)
siempre se puede usar para llamar explícitamente a la plantilla tomando un argumento de plantilla, pero no hace ninguna deducción de los argumentos.range1
replica la deducción de lastrf::range
plantilla original .Esto funciona porque [temp.deduct.funcaddr] / 1 dice que la deducción de argumentos de plantilla al tomar la dirección de una función sin el tipo de destino de la conversión se realiza en cada plantilla de función candidata como si las listas de parámetros y argumentos de una llamada hipotética fueran vacío. Por lo tanto, el segundo argumento de plantilla no se puede deducir para la segunda sobrecarga con dos parámetros de plantilla. El único candidato que queda es la primera sobrecarga, que se elegirá como el objetivo del puntero de función.
Siempre que no haya una segunda plantilla de función candidata para la cual se pueda formar una ID de plantilla válida con un solo argumento,
range1_ptr
siempre se puede usar para llamar a la plantilla de función tomando un argumento sin ambigüedades. De lo contrario, la instanciación derange1_ptr
dará un error debido a la ambigüedad.fuente
strf::range<T>
?pretty_please_with_sugar_on_top()
? ... C ++ puede ser tan raro a veces ...¿Qué hay de pasar por un
using
?fuente
range()
versión es compatible contpf
; otro caso puede ser diferente.tfp x = &strf::range<char const *>;
); de esta manera, supongo que tiene una solución general, casi equivalente a la de la nuezUna solución es
1) en primer lugar, debe especificar el tipo para el segundo argumento, p. Ej.
(char *)(some_char_ptr + some_length)
2) no use
const
para ambos, esto funciona bien:Puede intentar reemplazar
(char *)
con(const char *)
a la izquierda O a la derecha, todavía funciona.fuente
const
datos.