访问另一个结构中的结构字段

时间:2019-01-17 14:25:18

标签: c++ struct c++14

假设我有结构

struct A
{
  int x;
};

,并且可以通过以下方式引用x字段 &A::x

我的问题是,在下面的情况下(C ++ 14),我可以做类似的事情(指x)吗? :

struct A
{
  struct B
  {
    int x;
  };

  B b;
};

好的,所以有一个更复杂的例子:

这有效:

struct A
{
    int x;
};

template <typename U, typename V, typename W>
void setField(U& object, V U::* field, W&& value)
{
    object.*field = std::forward<W>(value);
}

int main()
{
  auto x = 5;
  A a;
  a.x = 0;
  std::cout << a.x << std::endl;
  setField(a, &A::x, x);
  std::cout << a.x << std::endl;
}

当我想获取更深的变量时,它不会:

struct A
{
    struct B
    {
        enum myEnum
        {
            E_0 = 0,
            E_1 = 1
        };
        myEnum e;
    };
    B b;
};

template <typename U, typename V, typename W>
void setField(U& object, V U::* field, W&& value)
{
    object.*field = std::forward<W>(value);
}

int main()
{
  auto m_enum = A::B::myEnum::E_0;
  A a;
  a.b.e = m_enum;
  std::cout << a.b.e << std::endl;
  setField(a, &A::B::e, m_enum);
  std::cout << a.b.e << std::endl;
}

错误日志:

31:31: error: no matching function for call to 'setField(A&, A::B::myEnum A::B::*,A::B::myEnum&)'

31:31: note: candidate is:

20:6: note: template<class U, class V, class W> void setField(U&, V U::*, W&&)

20:6: note: template argument deduction/substitution failed:

31:31: note: deduced conflicting types for parameter 'U' ('A' and 'A::B')

2 个答案:

答案 0 :(得分:2)

您应该写:

setField(a.b, &A::B::e, m_enum);

代替

setField(a, &A::B::e, m_enum);

答案 1 :(得分:1)

您可以轻松完成

&A::B::x

这为您提供了xA::B的地址。要对其进行评估,需要一个A::B类型的对象,在您的情况下,可以通过对&A::b类型的对象进行评估的A来访问它。因此,您需要取消引用的级别。