Bonjour à toutes et à tous


Je suis en train de me faire une fonction pour convertir en chaîne de caractères les objets de mon api. J'utilise c++14. Mais si vous avez une solution en c++17 ou c++20 n'hésitez pas à la proposer car même avec ces normes je ne vois pas comment faire :p.
Du coup j'ai des nombres, des pair, des conteneurs (je ne mets pas les tuples pour le moment mais si ça intéresse quelqu'un d'itérer sur un tuple -> https://stackoverflow.com/questions/...dtuple-in-c-11)


L'idée est d'appeler to_string avec un objet ou un nombre en paramètre et d'avoir en retour leur représentation en chaîne de caractères. La représentation dans l'exemple est un exemple simple pour développer l'algorithme.

J'ai trouvé une solution pour les conteneurs mais ça m'oblige à définir un template pour chaque type de conteneur.
J'aurais bien aimé une seule fonction qui chapeaute tout les conteneurs.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
 
template <typename T_Container>
std::string to_string(const T_Container& value) 
{
    std::stringstream ss;  
    ss << "{" ;
 
    for(auto it : value)    
        ss << to_string(*it);
 
    ss << "}";
    return ss.str();
}

Le problème c'est qu'elle ne permet pas au compilateur de la différencier de la fonction pour les types simples:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
template <typename T>
std::string to_string(T value) 
{
    std::stringstream ss;
    ss.precision(std::numeric_limits<T>::digits10);
    ss << "T: " << value;
    return ss.str();
}
Auriez-vous une idée ?

Un grand merci.

Voici le code.

Lien vers coliru pour éditer le code:
https://coliru.stacked-crooked.com/a/c3e36f81070384ea
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
 
#include <iostream>
#include <sstream>
#include <limits>
#include <map>
 
template <typename T>
std::string to_string(T value) 
{
    std::stringstream ss;
    ss.precision(std::numeric_limits<T>::digits10);
    ss << "T: " << value;
    return ss.str();
}
 
template <>
std::string to_string(long value) 
{
    std::stringstream ss;
    ss.precision(std::numeric_limits<long>::digits10);
    ss << "long: " << value;
    return ss.str();
}
 
template <typename T1, typename T2>
std::string to_string(const std::pair<T1, T2>& value) 
{
    std::stringstream ss;
    ss << "{" << to_string(value.first) << ", " << to_string(value.second) << "}";
    return ss.str();
}
 
/*
template <typename T_Container>
std::string to_string(const T_Container& value) 
{
    std::stringstream ss;  
    ss << "{" ;
    
    for(auto it : value)    
        ss << to_string(*it);
    
    ss << "}";
    return ss.str();
}
 
/*/
template <typename ... Ts>
std::string to_string(const std::map<Ts...>& value) 
{
    std::stringstream ss;  
    ss << "{" ;
 
    for(auto it : value)    
        ss << to_string(it);
 
    ss << "}";
    return ss.str();
}
//*/
 
int main()
{
    long toto_long = 1;
    float toto_float = 2.3f;
    std::pair<long, float> toto_pair = {toto_long, toto_float};
    std::map<long, float> toto_map_less = {{toto_long, toto_float}, {toto_long*2, toto_float}};
    std::map<long, float, std::greater<long>> toto_map_greater = {{toto_long, toto_float}, {toto_long*2, toto_float}};
 
    std::cout << to_string(toto_long) << " " << to_string(toto_float) << std::endl;    
    std::cout << to_string(toto_pair) << std::endl;    
    std::cout << to_string(toto_map_less) << std::endl;
    std::cout << to_string(toto_map_greater) << std::endl;
}
Le résultat attendu:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
 
long: 1 T: 2.3
 
{long: 1, T: 2.3}
 
{{long: 1, T: 2.3}{long: 2, T: 2.3}}
 
{{long: 2, T: 2.3}{long: 1, T: 2.3}}