приведение коротких * / двойных * к int * и обратно и разыменование

0

поскольку я совершенно новичок в 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 байтов с начала сохраненного адреса. Фактически, это работало хотя бы с шортами, но я не уверен, что это просто совпадение, и я должен быть уверен.

Опять же, я сожалею, если это полная глупость и заранее заблаговременно за ответы на ум.

  • 2
    Вау, это звучит очень, очень подозрительно. Что вы на самом деле пытаетесь сделать? Это, скорее всего, проблема XY.
  • 0
    Он будет работать с шортами, но не с двойными. Приведение двойного к int - это конверсия с потерями.
Показать ещё 3 комментария
Теги:

2 ответа

0
Лучший ответ

Вы всегда можете наложить указатель на указатель на другой тип, даже если вам нужно пройти через указатель 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

И мои советы:

  • не используйте это, если у вас нет веских оснований для этого
  • никогда не используйте его в реальном приложении
  • 0
    Спасибо ... это то, что я в конечном итоге хотел знать, поскольку я просто не был уверен, что это не случайно, что это сработало на моей машине. Причина, по которой мне нужно что-то подобное, заключается в том, что я взаимодействую с другим приложением. Это SDK (и библиотека), определяющие структуру с большим количеством целых (и коротких и двойных), которые я хотел бы прочитать из нее в зависимости от запроса пользователя (ввод в виде строки). Таким образом, я подумал, что было бы лучше сделать это так ... хранить указатели и разыменование по мере необходимости. Поскольку шорт и удвоение на самом деле не так много, я бы сделал небольшую комбинацию if / else, чтобы выяснить, какой бросок использовать.
3

Если вы хотите сохранить указатель на некоторые произвольные данные, то, возможно, одним из простейших способов использования является тегированный союз, такой как 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;
  • 1
    Может быть, отказаться от указателей тоже.
  • 0
    @LightnessRacesinOrbit Не был уверен, что указатели были требованием.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню