std::thread and rvalue reference

不问归期 提交于 2019-12-11 12:52:36

问题


I wanted to have some kind of delegator class. Shortened version of my approach is below and it's main functionality is to start new thread doing some thing (in this example it prints text every second):

void Flusher::start(){
    m_continue.store(true);

    m_thread = std::thread([](std::atomic<bool>& shouldContinue){
        while(shouldContinue.load()){
            std::this_thread::sleep_for(std::chrono::seconds(1));
            std::cout << "sec passed" << std::endl;
        }}, std::ref<std::atomic<bool>>(m_continue)
    );
}

My concern is, that std::thread constructor has following signature:

template< class Function, class... Args > 
explicit thread( Function&& f, Args&&... args );

So it takes rvalue reference as the first and second argument. If it's so, then I should not use shouldContinue after passing it to the std::thread constructor as it was moved.

Of course I want to have control over this function and therefore I want to use shouldContinue in a caller thread to stop called function. For obvious reasons I do not want to make this variable global.

I think, that std::ref makes some magic there, but I am still not sure how does it work (I saw std::ref in some examples when creating new thread).

I tried to not care at all about the fact, this is rvalue reference and I used shouldContinue later on and nothing crashed, but I fear this is simply undefined behavior. Could anyone tell if above code is correct and if not, how to do this correctly?


回答1:


There is a special type deduction rule when && is used with templates.

Check this out for a really good explanation:

http://eli.thegreenplace.net/2014/perfect-forwarding-and-universal-references-in-c/

template <class T>
void func(T&& t) {
}

"When && appears in a type-deducing context, T&& acquires a special meaning. When func is instantiated, T depends on whether the argument passed to func is an lvalue or an rvalue. If it's an lvalue of type U, T is deduced to U&. If it's an rvalue, T is deduced to U:"

func(4);            // 4 is an rvalue: T deduced to int

double d = 3.14;
func(d);            // d is an lvalue; T deduced to double&

float f() {...}
func(f());          // f() is an rvalue; T deduced to float

int bar(int i) {
  func(i);          // i is an lvalue; T deduced to int&
}

Also, reference collapsing rule is a good read.



来源:https://stackoverflow.com/questions/32809192/stdthread-and-rvalue-reference

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!