如何在c ++中复制Delphi的索引属性?

时间:2019-01-28 14:30:50

标签: c++ delphi properties

我希望能够拥有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声明为UINT32 *const Data4 = (UINT32 *)&Data8;
在struct中没有帮助,因为这为我增加了8个字节,这不是我想要的。
我希望翻译是无缝的。

我该怎么做?

我当时正在考虑重载[]运算符,但是有必要将Data4设为子结构,即使这样,我不确定如果我想让所有内容都可以内联地工作(即没有任何运行时开销)。

使用联合有效,但是我需要在客户端代码中键入的点数已经超出了这个范围(classname.unionname.datamember.arrayname[index]

2 个答案:

答案 0 :(得分:6)

如果且仅当正在使用C ++ Builder时,您可以使用其__property扩展名,它与Delphi的property直接等效,例如:

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];
    };
};

答案 1 :(得分:2)

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;
};

用法保持不变,嵌套类可能会使用其内部容器的数据类型,并直接在其内部容器中转发后者的功能。