передавая аргумент конструктору boost :: thread constructor [duplicate]

Если кто-то ищет Linq verson, это работает для меня:

public static IQueryable<BlockVersion> LatestVersionsPerBlock(this IQueryable<BlockVersion> blockVersions)
{
    var max_version_per_id = blockVersions.GroupBy(v => v.BlockId)
        .Select( v => new { BlockId = v.Key, MaxVersion = v.Max(x => x.Version) } );    

    return blockVersions.Where( v => max_version_per_id.Any(x => x.BlockId == v.BlockId && x.MaxVersion == v.Version) );
}
41
задан contrapsych 3 January 2011 в 02:17
поделиться

5 ответов

Ключевое слово this используется с boost::bind, когда объект функции, который вы создаете, привязан к функции объекта-объекта . Функции-члены не могут существовать отдельно от экземпляров, поэтому при создании объекта-функтора из функции-члена с boost::bind вам нужен указатель на экземпляр. Именно это и есть ключевое слово this. Если вы используете ключевое слово this внутри функции-члена класса, то вы получаете указатель на текущий экземпляр этого класса.

Если вы должны были вызвать bind из за пределами функция члена класса, вы можете сказать что-то вроде:

int main()
{
  Foo f;
  boost::thread* thr = new boost::thread(boost::bind(&Foo::some_function, &f));
}

Здесь мы используем Foo :: some_function как нашу функцию потока. Но мы не можем использовать this, потому что мы вызываем bind из main. Но то же самое можно было бы сделать с помощью this, если мы назовем bind изнутри функции-члена Foo, например:

void Foo::func1()
{
  boost::thread* thr = new boost::thread(boost::bind(&Foo::some_function, this));
}

Если функция-член статична или просто является регулярной (не-член), тогда вам вообще не нужен указатель на экземпляр. Вы просто сделали бы:

boost::thread* thr = new boost::thread(some_regular_function);
77
ответ дан Charles Salvia 26 August 2018 в 22:20
поделиться

Если ваш объект является функтором, то есть имеет operator(), вы можете передать его экземпляр в boost::thread. operator() не обязательно быть статичным. Например:

#include <boost/thread.hpp>

struct th {
    void operator()();
};

void th::operator()()
{
    for (;;) {
        // stuff
    }
}

int main()
{
    th t;
    boost::thread my_thread( t ); // takes a copy of t !
    my_thread.join(); // blocks
    return 0;
}
1
ответ дан Bulletmagnet 26 August 2018 в 22:20
поделиться

В подобных случаях полезно использовать нестатические функции-члены как свободные функции, которые принимают this в качестве первого параметра, например, в вашем случае void MainThreadFunc(Main* this).

boost::thread принимает нулевой функтор, поэтому вам нужно передать ему нулевой функтор, который содержит ссылку на экземпляр GUIMain и вызовы GUIMain->MainThreadFunc, которые, как я объяснил выше, были бы чем-то как MainThreadFunc(GUIMain).

Boost (и теперь также C ++ с TR1) предоставляет помощники для создания таких функторов, а именно boost::bind (или, альтернативно, boost::lambda::bind). Выражение boost::bind(f, arg1, arg2, ...) означает «вернуть нулевой функтор, который вызывает f(arg1, arg2, ...)».

При этом вы можете использовать следующее выражение для создания потока:

GUIThread = new boost::thread(boost::bind(&Main::MainThreadFunc, GUIMain))
3
ответ дан Giuseppe Ottaviano 26 August 2018 в 22:20
поделиться

Как уже упоминалось, когда вы хотите вызвать метод объекта в новом потоке, вы должны указать адрес этого объекта. Но вам не нужно вызывать boost::bind, вы можете использовать перегруженный конструктор boost::thread следующим образом:

GUIThread = new boost::thread(&Main::MainThreadFunc, GUIMain);

Если метод находится в том же классе, вы используете this, чтобы получить адрес текущего экземпляра, например:

t = new boost::thread(&myclass::compute, this);

Если у метода есть параметры, вы можете указать их после второго аргумента, например:

t = new boost::thread(&myclass::compute, this, p1, p2);
39
ответ дан maxschlepzig 26 August 2018 в 22:20
поделиться

boost :: bind - ваш друг (иногда может быть грубый способ показать его)!

использовать GUIThread = new boost::thread(boost::bind(&Main::MainThreadFunc, GUIMain));

, а затем сделать ваш MainThreadFunc регулярным членом , Это означает, что вы можете использовать переменные экземпляра напрямую, как обычно.

Что-то вроде этого:

class GUIMain {
public:
  GUIMain() : m_Member(42) {}

  void MainThreadFunc() {
    // use all members as you would normally do
    std::cout << m_Member << std::endl;
  }

private:
  int m_Member;
};
3
ответ дан villintehaspam 26 August 2018 в 22:20
поделиться
Другие вопросы по тегам:

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