Sie müssten einen Typ verwenden, der Instanzen eines der Typen speichern kann, die Sie speichern möchten.
Es gibt mehrere Verfahren, z.B. Varianten.
Eine Möglichkeit ist:
class Foo {
public:
enum class Type : char { Int16, Uint16 };
static Foo Int16 (int v) { Foo ret{Type::Int16}; ret.int16_ = v; return ret;}
static Foo Uint16 (unsigned int v) { Foo ret{Type::Uint16}; ret.uint16_ = v; return ret;}
int16_t as_int16() const { assert_(Type::Int16); return int16_; }
uint16_t as_uint16() const { assert_(Type::Uint16); return uint16_; }
Type type() const { return type_; }
private:
Foo (Type type) : type_(type) {}
void assert_(Type t) const { if (t != type_) throw "meh"; }
union { int16_t int16_; uint16_t uint16_; };
Type type_;
};
Beispiel:
int main() {
Foo f = Foo::Int16(4);
std::cout << f.as_int16() << '\n'; // okay
//std::cout << f.as_uint16() << '\n'; // exception
Foo g = Foo::Uint16(4);
std::cout << f.as_uint16() << '\n'; // okay
//std::cout << f.as_int16() << '\n'; // exception
// Switch on its type:
switch (g.type())
{
Foo::Type::Int16: std::cout << g.as_int() << '\n'; break;
Foo::Type::Uint16: std::cout << g.as_uint() << '\n'; break;
}
}
Dies ist im Grunde ein union
die eine Ausnahme auslösen, wenn Sie versuchen, int
zu lesen, aber wirklich unsigned int
gespeichert; Kinda union
das wurde schwer zu benutzen-falsch gemacht.
boost::variant
wäre eine andere Option.
Eine dritte Variante, wie bereits von R. Martinho Fernandes erwähnt, wäre die Verwendung eines größeren, signierten Int. Es hängt von Ihrem Anwendungsfall ab, ob Tippfehler relevant sein kann, wenn Sie T speichern und dann als U lesen möchten, wenn Sie Besucher mögen, wenn Sie den Typ überhaupt verfolgen möchten, und so weiter.
Meine gespeicherte Lösung ist auf meinem System 4 Byte groß (wegen der Ausrichtung), ebenso wie eine größere Ganzzahl mit Vorzeichen. Ich denke, weil Sie Ihre Werte in einem Container speichern, wird es nicht möglich sein, die Typ-Tracking während bleiben 2 Bytes zu verpassen, so dass ich denke, Ihr Minimum ist 4 Bytes in jedem Fall.
Haben Sie versucht, 'uint16_t' als zweiten Vorlagentyp für den Container zu verwenden, in dem Sie nicht signierte Ints speichern werden? – Alexander
Hallo Alexander, ich wusste nicht, dass du das kannst. – Kam
@Alexander: Was genau meinst du? Vielleicht ein Erklärungsbeispiel geben? –