Estou usando uma biblioteca C ++ ( strf ) que, em algum lugar dentro dela, tem o seguinte 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) { /* ... */ }
}
Agora, quero usar strf::range<const char*>(some_char_ptr, some_char_ptr + some_length)
no meu código. Mas, se o fizer, obtenho o seguinte erro (com o NVCC da 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)
O código da biblioteca provavelmente pode ser alterado para evitar isso (por exemplo, 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)
garantir que Range
não seja um ponteiro); mas não posso fazer essa alteração agora. Em vez disso, quero de alguma forma indicar ao compilador que realmente pretendo ter apenas um argumento de modelo, não um especificado e outro deduzido.
Posso fazer isso?
Gostaria de receber respostas para C ++ 11 e C ++ 14; As respostas C ++ 17 que envolvem guias de dedução são menos relevantes, mas se você tiver uma, publique-a (para versões futuras do NVCC ...)
Atualização: A própria biblioteca strf foi atualizada para contornar essa situação, mas a pergunta permanece conforme a pergunta.
char*
mas não seja, não é uma solução?Respostas:
Em seguida, ligue em
range1
vez destrf::range
.range1_ptr<T>(...)
sempre pode ser usado para chamar explicitamente o modelo usando um argumento de modelo, mas não deduz os argumentos.range1
replica a dedução dostrf::range
modelo original .Isso funciona, porque [temp.deduct.funcaddr] / 1 diz que a dedução de argumento do modelo ao obter o endereço de uma função sem o tipo de destino da conversão é feita em cada modelo de função candidato como se o parâmetro e a lista de argumentos de uma chamada hipotética fossem esvaziar. Portanto, o segundo argumento do modelo não pode ser deduzido para a segunda sobrecarga com dois parâmetros de modelo. O único candidato que resta é a primeira sobrecarga, que será escolhida como o alvo do ponteiro da função.
Desde que não haja um segundo modelo de função candidato para o qual um ID de modelo válido com apenas um argumento possa ser formado,
range1_ptr
sempre pode ser usado para chamar o modelo de função usando um argumento sem ambiguidade. Caso contrário, a instanciação derange1_ptr
dará um erro por causa da ambiguidade.fonte
strf::range<T>
?pretty_please_with_sugar_on_top()
? ... C ++ pode ser tão esquisito às vezes ...Que tal passar por um
using
?fonte
range()
versão é compatíveltpf
; outro caso pode ser diferente.tfp x = &strf::range<char const *>;
); Desta forma, eu suponho que você tem uma solução geral, quase equivalente a um da nozUma solução é
1) primeiro, você deve especificar o tipo para o segundo argumento, por exemplo
(char *)(some_char_ptr + some_length)
2) não use
const
para os dois, isso funciona bem:Você pode tentar substituir
(char *)
por(const char *)
à esquerda OU à direita, ainda funciona.fonte
const
dados.