Comment puis-je éviter les conversions implicites sur la non-construction de fonctions?
Comment puis-je éviter la conversion implicite sur la non-construction de fonctions?
J'ai une fonction qui prend un entier en paramètre,
mais cette fonction prendra également des caractères, booléens, et qu'il désire.
Je crois qu'il le fait par implicitement casting eux.
Comment puis-je éviter cela, de sorte que la fonction accepte uniquement les paramètres d'un même type, et refusera de compiler autrement?
Il y a un mot-clé "explicite", mais il ne fonctionne pas sur la non-construction de fonctions. :\
que dois-je faire?
Le programme suivant compile, mais j'aimerais ne pas:
#include <cstdlib>
//the function signature requires an int
void function(int i);
int main(){
int i{5};
function(i); //<- this is acceptable
char c{'a'};
function(c); //<- I would NOT like this to compile
return EXIT_SUCCESS;
}
void function(int i){return;}
*s'il vous plaît assurez-vous de signaler toute utilisation abusive de la terminologie et des hypothèses
- par la manière, la capacité de passer d'un char, long, bool, ou n'importe quel autre type entier où un int est prévu, c'est parce que de l'entier de la promotion et des règles de conversion qui sont intégrés dans la langue. Ce mécanisme est différent que les conversions implicites de non-explicite des constructeurs.
- +1 pour la question sans vraiment de bonnes solutions encore!
Vous devez vous connecter pour publier un commentaire.
Vous ne pouvez pas directement, car un
char
est automatiquement promuint
.Vous pouvez recourir à une astuce cependant: créer une fonction qui prend un
char
comme paramètre, et ne pas la mettre en œuvre. Elle compile, mais vous aurez une erreur de l'éditeur de liens:L'appel de la fonction avec un
char
paramètre briser la construction.Voir http://ideone.com/2SRdM
Terminologie: non-construcing fonctions? Voulez-vous dire une fonction qui n'est pas un constructeur?
=delete
et obtenir un erreur de compilation, pas une erreur de l'éditeur de liens.char
. Éventuellement, le nombre d'indésirables réels types d'argument est sans limite. Donc le cas général ferait appel à un assez grand nombre de déclarations de fonction. Le "évident" la solution à templatize. Mais alors, on supprime la possibilité d'avoir un général basé sur un modèle de surcharge.char
àint
.Définir la fonction de modèle qui correspond à tous les autres types:
C'est parce que les non-modèle avec des fonctions directes de correspondance sont toujours considérés en premier. Ensuite, le modèle de fonction directe de match sont considérés - si jamais
function<int>
sera utilisé. Mais pour autre chose, comme char,function<char>
sera utilisé - ce qui donne à votre compilation errrors:ERREURS:
C'est le C++03 façon:
hton
etntoh
fonctions qui ne fonctionne qu'avec le type de droit.Voici une solution qui provoque une erreur à la compilation si
function
est appelée avec rien mais un intIl fonctionne en permettant à n'importe quel type de l'argument à une fonction, mais à l'aide de
is_int
comme au niveau du type de prédicat. Le générique de la mise en œuvre deis_int
a une valeur fausse, mais la spécialisation explicite pour le type int a la valeur true pour que la statique de faire valoir les garanties que l'argument est exactement le typeint
sinon, il y a une erreur de compilation.value
.Bien, je vais répondre avec le code ci-dessous, mais même s'il travaille avec Visual C++, dans le sens de la production de leurs erreur de compilation MinGW g++ 4.7.1 accepte, et invoque la référence rvalue constructeur!
Je pense que ça doit être un bug du compilateur, mais je peux me tromper, donc – n'importe qui?
De toute façon, voici le code, qui peut être conforme à la norme de la solution (ou bien, il peut s'avérer que c'est un thinko de ma part!):
template <class T> void function(T) = delete;
....Pour le C++14 (et je crois que C++11), vous pouvez désactiver la copie constructeurs par la surcharge rvalue-références ainsi:
Exemple:
Disons que vous avez une base de
Binding<C>
classe, oùC
est soit la baseConstraint
classe ou d'une classe héritée. Dites que vous stockezBinding<C>
en valeur dans un vecteur, et que vous passez une référence à la liaison et vous souhaitez vous assurer que vous ne causent pas un implicite copie.Vous pouvez le faire en supprimant
func(Binding<C>&& x)
(par PiotrNycz l'exemple de rvalue-référence des cas spécifiques.Extrait de:
De sortie:
D'erreur (avec
clang-3.9
dansbazel
, lorsque la ligne incriminée est sans commentaire):L'Intégralité Du Code Source: prevent_implicit_conversion.cc
Peut-être vous pouvez utiliser une structure pour faire la deuxième fonction privée:
Ce ne compile pas:
J'ai d'abord essayé PiotrNycz de l'approche (pour C++03, je suis obligé de l'utiliser pour un projet), puis j'ai essayé de trouver une approche plus générale et est venu avec cette
ForcedType<T>
classe de modèle.Si je ne me trompe pas, ces trois spécialisations devraient couvrir tous les cas d'utilisation courants. Je ne suis pas sûr si une spécialisation pour les rvalue-référence (sur le C++11 ans) est réellement nécessaire ou la valeur de l'un suffit.
On pourrait l'utiliser comme ceci, dans le cas d'une fonction de 3 paramètres dont le 3e paramètre ne permet pas de conversion implicite: