J'essaie d'écrire une fonction comme Le deuxième appel à J'utilise MSVC 2010 mais que vous voulez que le code soit généralement compatible C ++ 11. P> std :: for_ach code>, que, en plus de l'utilisation normale, pouvez également prendre un
std :: fonction
A.Visit ([&] (int) -> VOID) code> ne compile pas lors de l'évaluation! Visiteur (I) . Est-il possible de faire ce travail ou je suis en train d'aboyer le mauvais arbre? P>
#include <list>
#include <string>
#include <iostream>
struct A
{
std::list<int> _lst;
template<typename _F>
void visit(_F visitor)
{
for(std::list<int>::const_iterator it = _lst.begin(), end = _lst.end() ; it != end ; it++) {
int i = *it;
if (std::is_void<decltype(visitor(i))>::value) {
visitor(i);
} else {
if (!visitor(i)) { // <----- error C2171: '!' : illegal on operands of type 'void'
break;
}
}
}
}
};
int main(int argc, char* argv[])
{
A a;
// populate a
for (int i = 0 ; i < 10 ; i++) {
a._lst.push_back(i);
}
a.visit([](int i) -> bool {
std::cout << i << std::endl;
return i < 5;
});
a.visit([](int i) {
std::cout << i << std::endl;
});
}
3 Réponses :
Ce lambda ne renvoie pas de valeur, c'est pourquoi vous obtenez une erreur que "Visiteur" renvoie Void:
a.visit([](int i) -> bool { std::cout << i << std::endl; return true; });
Il manque le point. Les deux appels devraient fonctionner, l'objectif est de changer visiter code> pour le faire fonctionner.
Votre std :: is_void doit être fait à la compilation et ne peut pas être fait à l'intérieur du corps de la fonction. Cette utilisation de la surcharge de fonction fonctionnera:
C'est exactement ce que j'avais mal compris. Merci!!
Notez que déclinger (visiteur (0)) code> ne fonctionnera pas lorsque
0 code> n'est pas un argument valide pour
visiteur code>.
std :: résultat_of code> existe à cause de cela.
Il visitent une liste de int code> S non une liste de types de modèles inconnus.
Comme alternative, écrivez des surcharges de do_visit code> qui acceptent soit un
T * code> ou un
Void * code> et transmettez un
static_cast
std :: isame code>. Notez que la mise en œuvre actuelle est trop stricte quand même: elle nécessite que le type de retour de
visiteur code> est exactement
bool code>, non convertible vers
bool code>.
Voici comment je voudrais implémenter i utilisé for_almost_each code>; Je suis
à l'aide de noms d'espace std code> plus de paramétrages de type à des fins de la lisibilité.
is_convertible code>, car il semble avoir plus de sens que
isameame code>. p> p>
Merci beaucoup, j'ai accepté la réponse de @ Troy parce que c'était d'abord, mais j'apprends beaucoup de choses à lire les vôtres aussi!
Notez également l'utilisation de résultat_of code>, ce qui se comporte correctement indépendamment de la manière dont l'argument doit être construit; La réponse de Troy ne fonctionne que lorsque le foncteur accepte le littéral
0 code>.
@KYLE_WM: Vous devez sélectionner la meilleure réponse et peut changer votre esprit précisément parce que les réponses ultérieures peuvent être meilleures. IMO C'est un exemple si celui de cette dernière réponse.
@Msalters, OK, a changé. J'avais accepté la réponse de Troy parce qu'elle corrige directement l'erreur dans mon code d'exemple (qui semble bonne, didactiquement). Mais je peux voir comment cette réponse est plus générale / plus utile aux autres recherchant la même question. Merci pour votre contribution.
Le code des deux côtés de la branche If doit être correct et compilable, vous ne pouvez donc pas choisir en fonction de std :: is_void à l'intérieur du corps de la fonction.
Pourquoi utilisez-vous des noms commençant par un soulignement et une lettre majuscule telle que
_f code>?
C'est la convention que j'utilise pour les paramètres de modèle. Je pense que je l'ai choisi de regarder le code STL.
@KYLE_WM: Les implémentations de la bibliothèque essaient généralement très difficiles à éviter les affrontements de nom, même avec des macros méchantes (qui ne respectent pas la portée). La norme facilite sa vie en leur donnant une autorisation exclusive d'utiliser des noms en commençant par deux soulignes, une lettre de soulignement et de majuscule. Si vous n'écrivez pas à la mise en œuvre (ce qui signifie que vous souhaitez que votre code soit portable), vous ne devez pas utiliser ces identificateurs.
@Danielko Oh, c'est gênant. Merci pour les informations, je vais cesser d'utiliser.