Как мне дублировать индексированные свойства Delphi в c ++? - PullRequest
0 голосов
/ 28 января 2019

Я хотел бы иметь возможность иметь следующую конструкцию, существующую в Delphi, которая также работает в c ++

Сначала код Delphi:

type
  TSlice = record
  private
    function GetData4: UINT32; inline;
    procedure SetData4(Index: 0..15; Value: UINT32); inline;
  public
    Data8: array[0..7] of UINT64;
    property Data4[index: 0..15]: UINT32 read GetData4 write SetData4;
  end;

Теперь код на C ++, который у меня естьи работает:

struct TSlice {
    UINT64 Data8[8];

    __device__ __forceinline__ UINT32 * Data4() { return reinterpret_cast<UINT32*>(Data8); }
}

Тем не менее, я все еще должен написать

for (auto i = 0; i < 3; i++) {
    Slice->Data4()[lane * 4] = SliverPart;
    Slice->Data4()[lane * 4 + 1] = SliverPart;
}

Я действительно хотел бы сбросить () здесь: Slice->Data2[lane * 4]

ОбъявлениеData4 as UINT32 *const Data4 = (UINT32 *)&Data8;
В структуре не помогает, потому что это дает мне дополнительные 8 байтов, а это не то, что я хочу.
Я хочу, чтобы перевод был плавным.

Как я могу это сделать?

Я думал о перегрузке оператора [], но это потребовало бы сделать Data4 подструктурой, и даже тогда я не уверен, что это будетработать, если я хочу, чтобы все работало inline (т.е. без каких-либо накладных расходов).

Использование объединения работает, но количество точек, которые мне нужно набрать в коде клиента, находится за пределами этого мира (classname.unionname.datamember.arrayname[index])

Ответы [ 2 ]

0 голосов
/ 28 января 2019

Если и только если , вы используете C ++ Builder, то вы можете использовать его расширение __property, которое является прямым эквивалентом property Delphi, например:

struct TSlice
{
private:
    UINT32 GetData4(int Index);
    void SetData4(int Index, UINT32 Value);

public:
    UINT64 Data8[8];
    __property UINT32 Data4[int Index] = {read=GetData4, write=SetData4};
};

В других компиляторах C ++ это напрямую невозможно, но вы можете получить close с помощью некоторых вспомогательных прокси: например:

struct TSlice
{
private:
    UINT32 GetData4(int Index);
    void SetData4(int Index, UINT32 Value);

public:
    UINT64 Data8[8];

    TSlice() : Data4(*this) {}

    struct proxy
    {
    private:
        TSlice &m_slice;
        int m_index;

    public:
        proxy(TSlice &slice, int index) : m_slice(slice), m_index(index) {}

        operator UINT32() { return m_slice.GetData4(m_index); }
        proxy& operator=(UINT32 value) { m_slice.SetData4(m_index, value); return *this; }
    };

    struct property
    {
    private:
        TSlice &m_slice;

    public:
        property(TSlice &slice) : m_slice(slice) {}
        proxy operator[](int Index) { return proxy(m_slice, index); }
    };

    property Data4;
};

Или вы можете просто использовать анонимный союз:

struct TSlice 
{
    union {
        UINT64 Data8[8];
        UINT32 Data4[16];
    };
};
0 голосов
/ 28 января 2019

В C ++ такой функции нет.

Я думал о перегрузке оператора [], но для этого необходимо сделать Data4 подструктурой [...]

Но я думаю, что на самом деле это подход, к которому вы можете приблизиться к желаемому результату.Может быть, простой std::array уже предоставляет все, что вам нужно?

class WhatEver
{
public:
    std::array<int, 7> property;
};

WhatEver w;
w.property[0];
for(auto& p : w.property) { /* ... */ }

Если вам нужен более точный контроль доступа или std::array (или даже std::vector) окажется не в состоянии удовлетворить ваши потребности, некоторыесоответствующий класс-обертка может сделать это:

class Outer
{
public:
    class Inner
    {
    public:
        [...]& operator[](size_t index);
        [...] begin(); // to allow range based for loop
        [...] end();
        // and const versions of
    private:
        friend class Outer; // so that outer can use the internals
        Inner(); // constructors as needed, destructor, ...
        // data container(s) as needed
    };
    Inner property;
};

Использование остается прежним, вложенный класс может использовать типы данных своего внутреннего контейнера и просто перенаправлять функции последнего в свои собственные.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...