поскольку я совершенно новичок в C++ и все еще должен многому научиться, пожалуйста, несите меня и, возможно, какие-то глупые вопросы:
В принципе, я объявляю map<wstring, int*>
, так как большинство переменных, которые я собираюсь разыменовать и использовать, являются int
(4 байта). К сожалению, редкими являются double
(8 байтов) или short
(2 байта), и я не влияю на это. Ради простоты, и, поскольку я хочу что-то узнать, я бы хотел прочитать все указатели на одной карте. Вот мои мысли:
map[wstring] = (int*) short*;//or double*
Будет ли вышеупомянутая работа с точки зрения того, что только начало короткого или двойного адреса памяти сохраняется на карте, а не в фактическом содержимом памяти?
Как я знаю, какие ключи разные, я бы бросил указатели на их тип до разыменования:
short = *((short*) map[wstring]); // or double = *((double*) map[wstring]);
С моей точки зрения ограниченные знания это может сработать. Я бы сказал, что, хотя из сохраненного адреса памяти, как правило, читается 4 байта, так как это то, о чем была объявлена карта, теперь, запустив короткую * или двойную *, я говорю, что я хотел бы прочитайте 2 или 8 байтов с начала сохраненного адреса. Фактически, это работало хотя бы с шортами, но я не уверен, что это просто совпадение, и я должен быть уверен.
Опять же, я сожалею, если это полная глупость и заранее заблаговременно за ответы на ум.
Вы всегда можете наложить указатель на указатель на другой тип, даже если вам нужно пройти через указатель void. Но при разыменовании вы получите мусор, так как вы неправильно интерпретируете зону памяти.
Если у вас есть часть волшебства, чтобы знать, какие указатели на самом деле short *
или double *
, вы можете это сделать. Вот пример:
#include<iostream>
using namespace std;
int main()
{
double b = 0.5;
short h = 10;
int i = 5;
int *t[3] = { (int *) &b, (int *)&h, &i };
cout << *((double *) (t[0])) << " " << *((short *) (t[1])) << " " << *(t[2]) << endl;
return 0;
}
дает:
0.5 10 5
И мои советы:
Если вы хотите сохранить указатель на некоторые произвольные данные, то, возможно, одним из простейших способов использования является тегированный союз, такой как Boost.Variant:
typedef boost::variant<
int*,
double*,
short*
> SomePtr;
std::map<wstring, SomePtr> m;
Таким образом, вы можете безопасно хранить любые типы указателей и использовать различные функции, которые предоставляет тип variant
для получения значения (например, boost::apply_visitor()
). Теперь я не уверен, является ли указатель сохранения указателем или нет, но это работает так же хорошо, если вы используете его как variant<int, double, short>
.
Кроме того, если вы не хотите использовать Boost, вы можете написать свою версию этого варианта с union
и индексом:
class Variant {
union {
int* iptr;
double* dptr;
short* sptr;
};
int which;
public:
Variant(int* p): iptr(p), which(0) { }
Variant(double* p): dptr(p), which(1) { }
Variant(short* p): sptr(p), which(2) { }
// example
template <typename F>
void visit(F f) {
switch (which) {
case 0: f(iptr); break;
case 1: f(dptr); break;
case 2: f(sptr); break;
}
}
};
std::map<wstring, Variant> m;