Oto alternatywne rozwiązanie. Nic niekoniecznie bardziej eleganckiego lub zbyt wymyślnego, ale jest to podejście alternatywne. Zakłada on, że wszystkie klasy, które zamierzasz wywoływać to_string, mają funkcję ToString().
Oto szablon funkcji, który działa tylko z obiektami typu klasy i wywołuje funkcję ToString().
template<typename T, typename = std::enable_if_t<std::is_class<T>::value>>
std::string to_string(const T& t) {
return t.ToString();
}
Być może chcemy, aby działało również z std :: string.
template<>
std::string to_string(const std::string& t) {
return t;
}
Oto przykład używanego kodu. Zwróć uwagę na fikcyjny obszar nazw to_s. Domyślam się, że jeśli użyjesz std :: to_string w funkcji głównej, to pojawi się ona w naszej nazwie funkcji szablonu, więc musimy wprowadzić nazwę pośrednio w ten sposób. Jeśli ktokolwiek wie, jak to zrobić, byłbym wdzięczny za komentarz.
#include <cstring>
#include <iostream>
#include <string>
#include <type_traits>
union U {
double d;
const char* cp;
};
struct A {
enum State { kString, kDouble };
State state;
U u;
void Set(const char* cp) {
u.cp = cp;
state = kString;
}
std::string ToString() const {
switch (state) {
case A::kString : return std::string(u.cp); break;
case A::kDouble : return std::to_string(u.d); break;
default : return "Invalid State";
}
}
};
namespace to_s { using std::to_string; };
int main() {
using namespace to_s;
std::string str = "a nice string";
double d = 1.1;
A a { A::kDouble, {1.2} };
std::cout << "str: " << to_string(str) << ", d: " << to_string(d) << std::endl;
std::cout << "a: " << to_string(a) << std::endl;
a.Set(str.c_str());
std::cout << "a: " << to_string(a) << std::endl;
std::memset(&a, 'i', sizeof(a));
std::cout << "a: " << to_string(a) << std::endl;
}
Oto co mam:
str: ładny ciąg d: 1,100000
a: 1,200000
a: ładny ciąg
a: Nieprawidłowy State
Powiązane [Czy istnieje standardowy sposób konwertowania klasy na ciąg] (http://stackoverflow.com/q/33357480/ 1708801) –
Również http://stackoverflow.com/questions/234724/is-it-possible-to-serialize-and-deserialize-a-class-in-c – Lol4t0
@ShafikYaghmour Tak, może być .. Jednak rozwiązania tam jest próba przeciążenia to_string zamiast tworzenia klasy to_stringable –