Доступ к полю структуры в другой структуре - PullRequest
0 голосов
/ 17 января 2019

Предположим, у меня есть структуры

struct A
{
  int x;
};

и к полю х можно обратиться &A::x

У меня вопрос: могу ли я сделать что-то подобное (см. X) в случае ниже (C ++ 14)? :

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 голосов
/ 18 января 2019

Вы должны написать:

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

вместо

setField(a, &A::B::e, m_enum);
0 голосов
/ 17 января 2019

Вы можете просто сделать

&A::B::x

Это дает вам адрес x внутри A::B. Чтобы оценить его, вам нужен объект типа A::B, к которому в вашем случае может обращаться &A::b, оцениваемый на объекте типа A. Таким образом, вам понадобятся уровни разыменования.

...