J'utilise une bibliothèque C ++ ( strf ) qui, quelque part en elle, a le code suivant:
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) { /* ... */ }
}
Maintenant, je veux utiliser strf::range<const char*>(some_char_ptr, some_char_ptr + some_length)
dans mon code. Mais si je le fais, j'obtiens l'erreur suivante (avec le 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)
Le code de la bibliothèque peut probablement être modifié pour éviter cela (par exemple en utilisant:
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)
s'assurer Range
n'est pas un pointeur); mais je ne peux pas faire ce changement pour le moment. Au lieu de cela, je veux en quelque sorte indiquer au compilateur que je veux vraiment vraiment n'avoir qu'un seul argument de modèle, pas un spécifié et un autre déduit.
Puis-je faire cela?
Souhaiterait des réponses pour C ++ 11 et C ++ 14; Les réponses C ++ 17 impliquant des guides de déduction sont moins pertinentes mais si vous en avez un, veuillez le poster (pour les futures versions de NVCC ...)
Mise à jour: la bibliothèque strf elle-même a été mise à jour pour contourner cette situation, mais la question demeure telle qu'elle a été posée.
char*
mais n'en est-il pas un n'est pas une solution?Réponses:
Appelez ensuite
range1
au lieu destrf::range
.range1_ptr<T>(...)
peut toujours être utilisé pour appeler explicitement le modèle en prenant un argument de modèle, mais ne fait aucune déduction à partir des arguments.range1
réplique la déduction dustrf::range
modèle d' origine .Cela fonctionne, car [temp.deduct.funcaddr] / 1 indique que la déduction d'argument de modèle lors de la prise de l'adresse d'une fonction sans type cible de la conversion est effectuée sur chaque modèle de fonction candidat comme si les listes de paramètres et d'arguments d'un appel hypothétique étaient vide. Le deuxième argument de modèle ne peut donc pas être déduit pour la deuxième surcharge avec deux paramètres de modèle. Le seul candidat restant est la première surcharge, qui sera choisie comme cible du pointeur de fonction.
Tant qu'il n'y a pas de deuxième modèle de fonction candidat pour lequel un modèle-id valide avec un seul argument peut être formé,
range1_ptr
peut toujours être utilisé pour appeler le modèle de fonction en prenant un argument sans ambiguïté. Sinon, l'instanciation derange1_ptr
donnera une erreur en raison de l'ambiguïté.la source
strf::range<T>
?pretty_please_with_sugar_on_top()
? ... C ++ peut être si bizarre parfois ...Et si vous passiez par un
using
?la source
range()
version est compatible avectpf
; l'autre cas peut être différent.tfp x = &strf::range<char const *>;
); de cette façon, je suppose que vous avez une solution générale, presque équivalente à celle du noyerUne solution est
1) tout d'abord, vous devez spécifier le type du deuxième argument, par exemple
(char *)(some_char_ptr + some_length)
2) ne pas utiliser
const
pour les deux, cela fonctionne bien:Vous pouvez essayer de le remplacer
(char *)
par(const char *)
à gauche OU à droite, cela fonctionne toujours.la source
const
données.