2014-02-14 3 views
4

Рассмотрим следующий код:Создание экземпляра shared_ptr <std::thread> с make_shared <std::thread>

class A 
{ 
    .... 
    shared_ptr<std::thread> mThread; 
    void Step(); 
    void LaunchTrhead(); 
} 

void A::LaunchThread() 
{ 
    ... 
    mThread=make_shared<std::thread>(Step); // This line gives an error 
    ... 
} 

void A::Step() 
{ 
    ... 
} 

Я пытаюсь инициализировать общий указатель mThread так, что она вызывает функцию Шаг. Однако компилятор дает мне ошибку «неверная инициализация ссылки типа ... из выражения типа« неразрешенный перегруженный тип функции »». Очевидно, я делаю что-то глупое, но я не могу на него наложить. Может ли кто-нибудь помочь? Заранее спасибо!

ответ

5

Step() является нестатической функцией-членом, поэтому он имеет неявный первый параметр типа A*. При вызове необходимо связать текущий экземпляр A.

mThread = std::make_shared<std::thread>(std::bind(&A::Step, this)); 

Вы также можете использовать лямбда вместо bind

mThread = std::make_shared<std::thread>([this]{ Step(); }); 

Как @Casey указывает в комментариях, std::thread's constructor имеет специальную обработку для указателя функций-членов, и будет считать, что первый следующий аргумент указатель или ссылку на экземпляр для вызова функции-члена. Это означает, что вы можете избежать bind и напрямую пройти this в качестве второго аргумента.

mThread = std::make_shared<std::thread>(&A::Step, this); 
+0

На месте! Компилятор рассказывал мне («неразрешенная функция»), но я просто не мог этого видеть, я был полностью ослеп (я должен пойти домой ...). Кроме того, в соответствии с тем, что вы указали, я могу объявить * Test * static. Но ваше решение более практично в моем случае, поскольку оно позволяет избежать указания указателя на объект владельца. Спасибо! – DrD

+1

Вы можете передать указатель на элемент и указатель на объект непосредственно в конструктор 'std :: thread' (и' std :: bind' и 'std :: async'):' mThread = std :: make_shared (& A :: Step, this); ' – Casey

+0

@Casey Не знал этого, спасибо! – Praetorian

1

Try (использование labda вместо свободной функции):

mThread=make_shared<std::thread>([this](){ Step(); }); 

Так оно и есть, вы не передаете ссылку на это в конструктор Inspite этого являющийся функцией-членом.

Это решение использует лямбда для создания объекта-объекта, который не принимает никаких параметров, но имеет ссылку на это.

Если вы хотите использовать глобальную функцию сделать это вместо того, чтобы, и двигаться void Step() раньше его использование:

mThread=make_shared<std::thread>(::Step()); 

:: устраняет неоднозначность за рамки функции.

+0

:: Шаг() Безразлично, т работу, извините. Решение лямбда делает. Благодаря! – DrD

+0

Вы переместили 'Step()' def defence до 'LaunchThread' – nishantjr

+0

Step() - это функция-член, только я забыл включить A :: в ее объявление. Теперь он отредактирован. Мои извинения. – DrD

0

Вы должны использовать shared_from_this() заменить этот

+0

Не могли бы вы предоставить более полный пример вашего предложения? – rsilva4

Смежные вопросы