2010-11-16 21 views
3

Je souhaite fournir une fonction de modèle qui convertit la plupart des types de base en chaîne. Le meilleur que je suis venu avec à ce jour est la suivante:Existe-t-il une fonction de modèle sans avertissement pour convertir les types de base en chaîne

template<typename T> inline std::string anyToString(const T& var) { 
    std::ostringstream o; 
    o << var; 
    return o.str(); 
} 

La fonction peut par exemple être utilisé pour les éléments suivants:

class TimeError:public std::runtime_error{ 
    public: 
     explicit TimeError(int time):std::runtime_error(anyToString(time)), 
     mTime(time){}; 
    protected: 
     int mTime; 
    }; 

Le problème avec anyToString et des fonctions similaires est la génération d'avertissements d'ambiguïté lors de la compilation avec gcc version 4.4.3 -Wall -Wexta -Werror "ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second "

A ma connaissance la raison de l'avertissement réside dans les possibilités de conversion implicite lors de l'appel < <

Ces ambiguïtés sont principalement générées par d'autres modèles comme suit:.

template<typename T> 
    T& operator<<(T& out, const SymRad& angle){ 
    return out << angle.deg(); 
    } 

Mais ceux-ci ont d'autres avantages comme travailler pour plusieurs types de flux. Alors j'aimerais les garder. Si je transforme le deuxième modèle en une méthode simple, par ex. ostream l'ambiguïté est nettoyée, mais je cherche sth. Cela permet de garder les deux modèles. Existe-t-il une fonction générique qui offre la même simplicité sans générer d'avertissement à l'aide des options décrites? Si non, quelle est la meilleure façon de localement désactiver l'avertissement émis?

+2

Hmm. Pouvez-vous ajouter un exemple de la façon dont vous utilisez ce modèle? –

+0

@Oli Charlesworth: a ajouté un exemple pour l'utilisation – Martin

+0

@Martin, de quelles options parlez-vous lorsque vous dites "ces options"? –

Répondre

2

Il semble que vous obtiendrez un message d'un scénario comme celui-ci:

#include <sstream> 
#include <string> 
#include <iostream> 

struct Y {}; 
struct X 
{ 
    operator Y() const {return Y(); } 
}; 

std::ostream& operator<< (std::ostream& os, X) { return os << "X"; } 
std::ostream& operator<< (std::ostringstream& os, Y) { return os << "Y"; } 

template<typename T> inline std::string anyToString(const T& var) { 
    std::ostringstream o; 
    o << var; 
    return o.str(); 
} 

int main() 
{ 
    std::cout << anyToString(X()) << '\n'; 
} 

Je vous recommande d'utiliser le drapeau -pedantic à la place. GCC le compile du tout grâce à une extension de compilateur, avec d'autres compilateurs ce sera une erreur directe.


Quant à votre ajout:

template<typename T> 
    T& operator<<(T& out, const SymRad& angle){ 
    return out << angle.deg(); 
    } 

Mais ceux-ci ont d'autres avantages comme travailler pour plusieurs types de flux.

Ceci ne fonctionne pas pour plusieurs types de flux. Par exemple si T est stringstream, alors out << angle.deg(); renverra probablement une référence à un ostream qui ne peut être implicitement rétrogradé à une référence stringstream.

+0

Bon exemple, j'ai ajouté la vraie source du mal à la description, mais votre exemple adresse tout de même. -pedantic regarde bien sur mon code mais j'utilise plusieurs librairies qt4 et celles-ci sont un cauchemar dans la génération d'alerte/erreur – Martin

+0

@UncleBens: Bon appel sur le problème de template pour 'operator <<', il est donc compatible uniquement avec les opérateurs définis dans un similaire mode. –

+0

@UncleBens: Je pensais que l'opérateur << structuré >> fonctionnerait par ex. pour les strings et les filestreams (std :: ofstream et std :: ostringstream). Corrigez-moi Si je me trompe – Martin

1

Votre compilateur supporte un #pragma dans ce but, autant que je sache - je sais que VC++ le fait. Cependant, vous pouvez simplement utiliser boost :: lexical_cast, aussi.

+0

'boost :: lexical_cast' échoue avec le même message pour un ensemble de surcharges similaire à celui démontré dans ma réponse (sauf qu'il utilise 'stringstream'). – UncleBens

+0

boost :: casting lexical fait l'affaire, mais je dois installer et inclure boost pour cette personne et d'autres personnes qui vont utiliser le modèle aussi. – Martin