Членский указатель на элемент массива

Я думаю, вы неправильно отформатировали функцию .show(). Попробуйте .show( duration [, easing ] [, complete ] )

$(".div3Btn").click(function() {
  $(".div2").show(5000, "swing", function() {
    // Animation complete.
  });
});
.div1 {
  display: flex;
  height: 100%;
  flex-direction: column;
  background-color: #919191;
}

.div2 {
  display: flex;
  overflow-y: auto;
  flex: 1;
  height: 500px;
  background-color: #a8d810;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="div1">
  <div id="div2" class="div2" style="display: none;">hjghjgjghj</div>
  <div class="div3">
    <button id="div3Btn" class="div3Btn">Click me!</button>
  </div>
</div>

14
задан tstenner 23 March 2009 в 19:21
поделиться

5 ответов

Проблема, то, что доступ к объекту в массиве является другим уровнем абстракции от доступа к простому интервалу. Если бы тот массив был указателем вместо этого, то Вы не ожидали бы мочь получить доступ к интервалу через членский указатель.

struct foo
{
  int a;
  int *b;
};

int main()
{

  foo bar;
  int foo::* aptr=&(*foo::b); // You can't do this either!
  bar.a=1;
  std::cout << bar.*aptr << std::endl;
}

То, что можно сделать, определяют функции членства, которые возвращают интервал, который Вы хотите:

struct foo
{
  int a;
  int *b;
  int c[2];

  int &GetA() { return a; } // changed to return references so you can modify the values
  int &Getb() { return *b; }
  template <int index>
  int &GetC() { return c[index]; }
};
typedef long &(Test::*IntAccessor)();

void SetValue(foo &f, IntAccessor ptr, int newValue)
{  
    cout << "Value before: " << f.*ptr();
    f.*ptr() = newValue;
    cout << "Value after: " << f.*ptr();
}

int main()
{
  IntAccessor aptr=&foo::GetA;
  IntAccessor bptr=&foo::GetB;
  IntAccessor cptr=&foo::GetC<1>;

  int local;
  foo bar;
  bar.a=1;
  bar.b = &local;
  bar.c[1] = 2;

  SetValue(bar, aptr, 2);
  SetValue(bar, bptr, 3);
  SetValue(bar, cptr, 4);
  SetValue(bar, &foo::GetC<0>, 5);
}

Затем у Вас, по крайней мере, есть последовательный интерфейс, чтобы позволить Вам изменять различные значения на нечто.

4
ответ дан 1 December 2019 в 15:12
поделиться

Однако компилятор просто жалуется на "недопустимое использование нестатического элемента данных 'нечто:: b'"

Это вызвано тем, что foo::a и foo::b имейте различные типы. Строго говоря, foo::b массив размера 2 из ints. Ваше объявление указателя должно быть совместимым т.е.:

int (foo::*aptr)[2]=&foo::b;

Действительно ли возможно сделать это вообще (или по крайней мере без объединений)?

Да, посмотрите ниже:

struct foo
{
  int a;
  int b[2];
};

int main()
{

  foo bar;

  int (foo::*aptr)[2]=&foo::b;
  /* this is a plain int pointer */
  int *bptr=&((bar.*aptr)[1]);

  bar.a=1; 
  bar.b[0] = 2;
  bar.b[1] = 11;

  std::cout << (bar.*aptr)[1] << std::endl;
  std::cout << *bptr << std::endl;
}

Обновленное сообщение с требованиями OP.

5
ответ дан 1 December 2019 в 15:12
поделиться

Вы не можете сделать этого из самого языка. Но Вы можете с повышением. Свяжите функтор с некоторым элементом того массива и присвойте его a boost::function:

#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
#include <boost/function.hpp>
#include <iostream>

struct test {
    int array[3];
};

int main() {
    namespace lmb = boost::lambda;

    // create functor that returns test::array[1]
    boost::function<int&(test&)> f;
    f = lmb::bind(&test::array, lmb::_1)[1];

    test t = {{ 11, 22, 33 }};
    std::cout << f(t) << std::endl; // 22

    f(t) = 44;
    std::cout << t.array[1] << std::endl; // 44
}
1
ответ дан 1 December 2019 в 15:12
поделиться
  typedef int (foo::*b_member_ptr)[2];
  b_member_ptr c= &foo::b;

все работы.

маленький прием для участника и использования указателей функции.
попытайтесь записать

char c = &foo::b; // or any other function or member pointer

и по ошибке компилятора Вы будете видеть ожидаемый тип для Вашего случая int (foo::*)[2].

Править
Я не уверен, что то, что Вы хотите, законно без этого указателя. Для добавляют 1 смещение к Вашему указателю, необходимо получить указатель на массиве от указателя на членском массиве. Но можно разыменовать членский указатель без этого.

0
ответ дан 1 December 2019 в 15:12
поделиться

Я не уверен, сработает это для вас или нет, но я хотел сделать то же самое и решил обойти это, подойдя к проблеме с другой стороны. В моем классе было несколько объектов, которые я хотел сделать доступными через именованный идентификатор или перебирать в цикле. Вместо того, чтобы создавать указатели на элементы где-нибудь в массиве, я просто объявил все объекты по отдельности и создал статический массив указателей на объекты

Примерно так:

struct obj
{
    int somestuff;
    double someotherstuff;
};

class foo
{
  public:
    obj apples;
    obj bananas;
    obj oranges;

    static obj foo::* fruit[3];

    void bar();
};

obj foo::* foo::fruit[3] = { &foo::apples, &foo::bananas, &foo::oranges };


void foo::bar()
{
    apples.somestuff = 0;
    (this->*(fruit[0])).somestuff = 5;
    if( apples.somestuff != 5 )
    {
        // fail!
    }
    else
    {
        // success!
    }
}



int main()
{
    foo blee;
    blee.bar();
    return 0;
}

Мне кажется, это сработало. Надеюсь, это поможет.

0
ответ дан 1 December 2019 в 15:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: