У меня есть класс, похожий на boost :: any, в том смысле, что это шаблонный класс-контейнер.Я хотел бы иметь метод для записи содержащегося значения в строку.Однако, если содержащийся тип не предоставляет оператор вставки потока, я бы хотел, чтобы мой метод возвращал некоторую строку по умолчанию, а не компилировал.Ниже приведено подробное описание того, что я пытаюсь сделать:
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();
}
};
}
Это работает довольно хорошо, с некоторыми оговорками.Например, если я хочу фактически предоставить перегруженный оператор вставки для класса, то этот оператор должен либо находиться в том же пространстве имен, что и класс, либо он должен находиться в пространстве имен W, чтобы его можно было рассмотреть.
У него также есть проблемы с любым типом, который уже имеет не член std :: operator <<, например, char и std :: string.Если T относится к одному из этих типов, то строка <code>oss << t_ выше становится неоднозначной.Это можно обойти, добавив перегрузки для этих типов в пространство имен W, например:
std::ostream& operator << (std::ostream& out, const std::string& s) {
return std::operator <<(out, s);
}
Мой вопрос: кто-нибудь нашел лучший метод, чем этот?Почему я должен добавить свои собственные перегрузки для таких вещей, как std :: string?Это все поддерживается в соответствии со стандартом, или я пользуюсь нестандартным поведением?(Я тестирую с g ++ 4.3.3)