7

メンバ ポインタを作成したいと思います。基本的に、メンバーが異なるメインクラスがあります。そのクラスのメンバーのメンバーを指すメイン クラスのメンバー ポインターを作成するにはどうすればよいですか。以下のコードが私がやろうとしていることを説明していることを願っています:

  struct SubUnit
  {
    int   value;
  };
  struct Unit
  {
    SubUnit sub_unit;
  };

  void Test()
  {
    SubUnit Unit::* ptr1 = &Unit::sub_unit; // WORKING
    int Unit::* ptr2 = &Unit::sub_unit::value; // NOT WORKING !
  }
4

4 に答える 4

5

あなたは2つの段階でそれをしなければならないようです:

SubUnit Unit::*pSub = &Unit::sub_unit;
int SubUnit::*pValue = &SubUnit::value;

Unit u;
int theVal = (u.*pSub).*pValue;
于 2014-01-28T15:37:31.750 に答える
3

一般にサブクラスは継承に使用されるため、サブクラスの使用はここで紛らわしいので、データメンバーについて話しましょう:sub_unitのデータメンバーですUnit

そして、あなたが求めていることは不可能であり、それ自体またはその基本クラスのUnit::*いずれかでのみオフセットを表すことができます:Unit

struct SubUnit { int value; };

struct Unit: SubUnit {};

int main() { int Unit::* p = &Unit::value; }
于 2014-01-28T15:23:46.590 に答える
2

これは、この質問の複製のようです:
Nested data member pointer - not possible?

受け入れられた答えの要点は次のとおりです。

メンバーへのポインターは &qualified_id 型の式によってのみ形成できますが、これはあなたの場合ではありません

C++ 標準の段落 8.3.3:
メンバーへのポインター:

宣言 TD で、D の形式は次のとおりです。

  nested-name-specifier * attribute-specifier-seqopt cv-qualifier-seqopt D1

ネストされた名前指定子はクラスを表し、宣言 T D1 の識別子の型は「派生宣言子型リスト T」であり、D の識別子の型は「派生宣言子型リスト T」です。 list cv qualifier-seq タイプ T のクラスのネストされた名前指定子のメンバーへのポインター。オプションの attribute-specifier-seq (7.6.1) は、メンバーへのポインターに関連します。

私の現在のコンパイラ(apple llvm 5.0)で動作しているようです。ただし、これは実装に大きく依存するため、このソリューションをいかなる種類のプロダクション コードでも使用しないことを強くお勧めします

//added a few data members to make it non-trivial
struct SubUnit {
    double d;
    int   value;
};
struct Unit {
    bool b;
    char c;
    SubUnit sub_unit;
};

intptr_t suOffset = offsetof(Unit, sub_unit);
intptr_t intOffset = offsetof(SubUnit, value);
intptr_t totalOffset = suOffset + intOffset;

// there is no way to convert this offset directly in a
// pointer-to-member AFAIK, so we have to trick a bit
int Unit::* pui = nullptr;
auto puiAddr = &pui;
intptr_t* puiAddrAsIntPtrPtr = reinterpret_cast<intptr_t*>(puiAddr);
*puiAddrAsIntPtrPtr = totalOffset;

//pui should now "point to the right offset"
//let's test it
Unit u;
u.sub_unit.value = 123456;

int val = u .* pui;
std::cout << "val: " << val << std::endl;
于 2014-01-28T15:32:31.930 に答える
0

ラムダを使用して回避策を構築できます。

    struct SubUnit
    {
        int   value;
    };
    struct Unit
    {
        SubUnit sub_unit;
    };

    void Test()
    {
        auto  composed_mem_ptr = [](Unit & unit) -> int&{ return  unit.sub_unit.value; };
        Unit  unit0{};
        composed_mem_ptr(unit0) = 7;
    }
于 2014-01-28T19:04:31.590 に答える