2017-05-15 4 views
1

Je pensais que j'allais faire un __DEBUG rapide et sale a permis le suivi avec quelque chose comme ceci:classe de débogage factice collée sur std :: endl surcharge

#ifdef __DEBUG 
# define dbg std::cout 
# define err std::cerr 
#else 

#include <iostream> 

class dummy_cout 
{ 
private: 

public: 
    dummy_cout & operator << (auto &obj) 
    { return *this; } 

    dummy_cout & operator << (std::result_of< decltype(&std::endl) >::type &obj) 
    { return *this; } 
}; 

# define dbg dummy_cout() 
# define err dummy_cout() 
#endif 


int main(int argc, char *argv[]) 
{ 
    dbg << "Bla, bla. bla..." << std::endl; 
} 

Mais il me donne:

cond_dbg.cpp:16:66: error: decltype cannot resolve address of overloaded function 
    dummy_cout & operator << (std::result_of< decltype(&std::endl) >::type &obj) 

J'ai également essayé une demi-douzaine de variations de decltype, result_of, ostream, etc. mais je n'ai pas encore obtenu d'autre mesure.

Ça devrait être simple. Si je compile le code définissant __DEBUG, j'aurais cout et cerr. Si je fais une compilation normale, j'aurais mon dummy_cout, qui ne fait simplement rien mais permet à mon code de compiler sans changements et peu de fouillis.

Toute aide sera grandement appréciée.

+0

Un commentaire sur votre opérateur '' << surcharge 'classe dummy_cout': C'est tout simplement pas comment vous surchargez C++' std :: insertion ostream' opérateurs .... – WhiZTiM

+1

Pourquoi avez-vous besoin de traiter 'std :: endl' séparément? Il devrait être capturé par la version modélisée. –

+0

Merci @Henri Menke. C'était mon tout premier procès mais ça n'a pas marché. 'template argument deduction/substitution failed' – j4x

Répondre

3

Vous ne pouvez pas écrire decltype(&std::endl) parce std::endl n'est pas une fonction, il est un modèle de fonction :

template< class CharT, class Traits > 
std::basic_ostream<CharT, Traits>& endl(std::basic_ostream<CharT, Traits>& os); 

En tant que tel, il ne dispose pas d'un type, donc il n'a pas de sens pour le demander. De plus, même s'il avait un type, l'enrobage result_of suivant n'aurait aucun sens.

La raison pour laquelle std::cout << std::endl œuvres est qu'il ya un overload qui accepte un type spécifique de pointeur de fonction:

basic_ostream& operator<<(
    std::basic_ios<CharT,Traits>& (*func)(std::basic_ios<CharT,Traits>&)); 

Cet opérateur n'est pas un modèle de fonction (il est fonction de membre de basic_ostream, qui est modèle de classe), et ainsi la résolution de surcharge déclenche ici l'instanciation d'une spécialisation de endl.

Pour que cela fonctionne, vous devez simplement faire la même chose:

dummy_cout& operator<<(std::ostream&(*p)(std::ostream&)); 

ou choisir une CharT et Traits approprié pour votre type factice:

dummy_cout& operator<<(std::basic_ostream<C,T>&(*p)(std::basic_ostream<C,T>&)); 

Juste une note . Cette déclaration est mal formé toute norme C++:

dummy_cout& operator<<(auto& obj); 

syntaxe du modèle de fonction Terse est une caractéristique des concepts TS, ce qui est encore un TS. À moins que vous utilisez - fconcepts, vous devez écrire:

template <class T> 
dummy_cout& operator<<(T& obj); 
+0

Ne devriez-vous pas signaler le problème avec la déclaration de la fonction membre:' dummy_cout & operator << (auto &obj); '? .. Ou est-ce maintenant une déclaration légale en C++ XX? – WhiZTiM

+0

@WhiZTiM Bien sûr, ajouté une note. – Barry

+0

Merci beaucoup @Barry. 'Dummy_cout & operator << (std :: ostream & (* p) (std :: ostream &))' fonctionne tout simplement hors de la boîte. Je viens d'éditer ma question pour montrer quelques résultats et je serais vraiment reconnaissant si vous pouviez commenter. – j4x