7
votes

Boost_check_equal avec paire et opérateur personnalisé <<

Lorsque vous essayez de faire un boost_check_equal (paire, paire), GCC ne trouve pas l'opérateur de flux pour paire, inspit-il de la déclarer. La chose drôle est que STD :: Out trouve l'opérateur. XXX PRE>

Ceci ne compile pas avec l'erreur: p>

...  instantiated from here
../boost-atp/release/include/boost/test/test_tools.hpp:326:9: error: no match for ‘operator<<’ in ‘ostr << t’


2 commentaires

Le nouveau de définition de votre propre impression pour des types personnalisés est expliqué ici: Stackoverflow.com/a/44810846/ 1617295 , et C'est la documentation officielle de cette fonctionnalité.


@Raffi Cette question ressemble à un duplicata de celui-ci, a moins de détails. Peut-être qu'il est logique de le marquer comme un duplicata et de déplacer votre réponse ici afin que nous ne puissions pas les utiliser? Je peux l'accepter aussi. Merci!


3 Réponses :


10
votes

Essayez de mettre le opérateur lui-même dans l'espace de noms STD :

namespace std
{
  ostream& operator<<(ostream& s, const pair<int,int>& p) {
    s << '<' << p.first << ',' << p.second << '>';
    return s;
  }
}


7 commentaires

Je ne comprends pas pourquoi ADL ne s'applique pas dans Boost_Check_equal. Boost Boost fait quelque chose pour arrêter cela de se produire?


@njr: Je l'ai regardé il y a quelque temps mais j'ai trouvé la cause fondamentale. AFAIK GCC fait ADL, de même que LLVM.


Cela fonctionne pour moi, mais cela semble être un comportement indéfini ( en.cppreference.com/w / CPP / Langue / Extending_std ). En regardant, j'ai découvert la réponse suivante qui donne un moyen d'éviter le comportement indéfini Stackoverflow.com/a/17573165/309334


@Ponyous n'aurait pas que cette affaire ne serait pas de tomber sous il est autorisé à ajouter des spécialisations de modèles pour tout modèle de bibliothèque standard à l'espace de noms de noms STD uniquement si la déclaration dépend d'un type défini par l'utilisateur et la spécialisation répond à toutes les exigences relatives au modèle d'origine < / i>?


L'exemple de "utilisation illégale" dans CPPreference utilise `opérateur + (STD :: paire , std :: paire ) qui est presque exactement ce que cette solution fait. Je pense que je dois sortir une copie de la norme.


bonnes nouvelles : l'exemple donné ne figure pas dans la norme de projet C ++ 14 (section N4296: 17.6.4.2.1). mauvaises nouvelles : le libellé de la norme est similaire à ce que vous avez cité. Les seules choses énumérées comme autorisées dans la norme sont des spécialisations de modèles. ostream et opérateur << (Ostream &, paire ) n'est pas une spécialisation de modèle, il s'agit d'une surcharge de fonction.


Le libellé est le suivant: le comportement d'un programme C ++ est indéfini s'il ajoute des déclarations ou des définitions à la norme Espace STD ou à un espace de noms dans le cadre de l'espace de noms STD, sauf indication contraire. Un programme peut ajouter une spécialisation de modèle pour tout modèle de bibliothèque standard à Nomspace STD uniquement si la déclaration dépend d'un type défini par l'utilisateur et la spécialisation répond aux exigences de la bibliothèque standard pour le modèle d'origine et n'est pas explicitement interdite.



0
votes

Je cherchais quelque chose de similaire, un moyen de personnaliser la chaîne de sortie pour imprimer des entiers dans Hex. Injecter un opérateur dans l'espace de noms STD fonctionnerait, mais chaque boost_check dans mon test serait imprimé en hexagone.

J'ai donc injecté des opérateurs personnalisés dans l'espace de nom de Boost que je pourrais contrôler avec des bools globaux.

Voir ma réponse ici Boost-check-échoue-à -Compile-opérateur-for-Types sur mesure .


0 commentaires

12
votes

Publier Opérateur Dans STD code> Comme Remus's Reshante est un comportement non défini dans le projet C ++ 14 (section N4296: 17.6.4.2.1). Boost fournit un crochet ( utilisé par cette réponse ) et vous pouvez écrire:

namespace boost
{
    namespace test_tools
    {
        namespace tt_detail
        {


1 commentaires

Ah! C'est génial! C'est beaucoup plus propre.