Я использовал подход, использующий оператор потока перегрузки решения @Begemoth <<, а затем добавил удобный метод "mixin" класса "toString" в тех случаях, когда требуется немедленная строка, например для отладки: </p>
template<typename T>
class ToString
{
public:
std::string toString() const
{
return convertToString(static_cast<const T&>(*this));
}
};
template<typename T>
inline std::string convertToString(const T& value)
{
std::stringstream s;
s << value;
return s.str();
}
Затем вы можете наследовать от этого класса в тех случаях, когда у вас есть оператор ostream, и он предоставит вам метод toString для этого класса.Если вы используете boost, то вы можете заменить реализацию convertToString, используя lexical_cast:
template<typename T>
inline std::string convertToString(const T& value)
{
return boost::lexical_cast<std::string>(value);
}
Если ваш класс предназначен для наследования и полиморфного доступа через указатели, то вышеупомянутое решение не будет работать, поскольку шаблоны связаны во время компиляциитак что нужен другой подход.Следующий класс mixin может использоваться вместо «ToString» выше, где определен виртуальный метод.Затем предоставляется вспомогательный макрос для реализации виртуальной функции в терминах функции шаблона "convertToString".Это должно быть добавлено в тело класса каждого производного класса, так как оно должно быть переопределено, а указатель «this» статически привязан к текущему типу.
class ToStringVirtual
{
public:
virtual ~ToStringVirtual() {}
virtual std::string toString() const = 0;
};
#define IMPLEMENT_ToStringVirtual public: std::string toString() const override { return convertToString(*this); }