web-dev-qa-db-fra.com

Comment puis-je empêcher C ++ de deviner un deuxième argument de modèle?

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 - 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)

pour s'assurer que Range n'est pas un pointeur); mais je ne peux pas faire ce changement pour le moment. Au lieu de cela, je tiens à 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 reste inchangée.

26
einpoklum

Une solution est

1) tout d'abord, vous devez spécifier le type du deuxième argument, par ex. (char *)(some_char_ptr + some_length)

2) n'utilisez pas const pour les deux, cela fonctionne bien:

strf::range((char *)some_char_ptr, (char *)(some_char_ptr + some_length));

Vous pouvez essayer de remplacer (char *) avec (const char *) à gauche OR à droite, cela fonctionne toujours.

0
tontonCD