Вам нужно будет использовать тип, который может хранить экземпляры одного из типов, которые вы хотите сохранить.
Существует несколько способов, например. варианты.
Одной из возможностей является:
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_;
};
Пример:
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;
}
}
Это в основном union
, что будет сгенерировано исключение при попытке чтения int
, но на самом деле хранится unsigned int
; Kinda union
, который был сделан трудно применимым-неправильным.
boost::variant
будет другой вариант.
Третий вариант, как уже упоминал Р. Мартиньо Фернандес, заключался бы в использовании большего, подписанного int. Это зависит от вашего прецедента, может ли быть неправильным, если вы хотите разрешить хранить T, а затем читать как U, если вам нравятся посетители, если вам нужно отслеживать тип вообще, и так далее.
Мое сохранение, отслеживание решения в моей системе на 4 байта (из-за выравнивания), как и большее целое число со знаком. Я думаю, потому что вы храните свои значения в контейнере, не удастся пропустить отслеживание типа, оставив 2 байта, поэтому, я думаю, ваш минимум составляет 4 байта в любом случае.
Вы пытались использовать 'uint16_t' в качестве второго типа шаблона для контейнера, в который собираетесь хранить неподписанные ints? – Alexander
Привет, Александр, я не знал, что ты можешь это сделать. – Kam
@ Александр: Что именно вы имеете в виду? Может быть, дать пример объявления? –