Mam klasę podobną do boost :: any, ponieważ jest to klasa kontenerów z szablonem. Chciałbym mieć metodę zapisu zawartej wartości na łańcuchu. Jeśli jednak zawartego typu nie zapewnia operator wstawiania strumienia, chciałbym, aby moja metoda zwróciła niektóre domyślne tring zamiast kompilacji. Poniżej jest tak blisko jak ja przyszedł i powinien jasno, co próbuję zrobić:Jak utworzyć "domyślny" operator wstawiania strumienia w C++?
namespace W {
namespace hide {
template <typename T>
std::ostream& operator<<(std::ostream& out, const T& t) {
return std::operator<<(out, typeid(T).name());
}
}
template <typename T> struct C {
T t_;
std::string ToString() const {
using namespace hide;
std::ostringstream oss;
oss << t_;
return oss.str();
}
};
}
To działa całkiem dobrze, z pewnymi zastrzeżeniami. Na przykład, jeśli chcę rzeczywiście dostarczyć przeciążonego operatora wstawiania dla klasy, wówczas ten operator musi albo być w tej samej przestrzeni nazw, co klasa, albo musi znajdować się w przestrzeni nazw W, aby mógł zostać uwzględniony.
Ma również problemy z każdym typem, który już ma std :: operator <, bez operatora, np. < <, np. char i std :: string. Jeśli T jest jednym z tych typów, linia oss << t_
powyżej staje się niejednoznaczna. Można to obejść dodając przeciążeń dla tych typów wewnątrz przestrzeni nazw W, na przykład:
std::ostream& operator << (std::ostream& out, const std::string& s) {
return std::operator <<(out, s);
}
Moje pytanie brzmi, czy ktoś znalazł lepszą metodą niż to? Dlaczego muszę dodawać własne przeciążenia dla rzeczy takich jak std :: string? Czy to wszystko jest obsługiwane zgodnie ze standardem, czy też korzystam z niestandardowego zachowania? (Testuję z g ++ 4.3.3)
Wygląda na to, że nie widzę żadnego z moich własnych niestandardowych operatorów wstawiania strumienia. Obiekt i operator const ma pierwszeństwo, może dlatego, że jest zadeklarowany jako część funkcji? Jeśli spróbuję wyciągnąć obiekt i jego operatora << z funkcji, to kończy się to, że nie mogę niczego dopasować ... – JimSteele1222
Właściwie to zróbmy: pobieramy operatory wstawiania strumienia, o ile są one w tej samej przestrzeni nazw co klasa T. Nie mogę znaleźć sposobu, aby na przykład zapewnić operator wstawiania strumienia dla wektora. –
JimSteele1222