簡體   English   中英

將成員函數用於std :: thread與std :: ref(* this)編譯失敗

[英]Use member function for `std::thread` with `std::ref(*this)` fails to compile

我使用下面的最小示例重現我嘗試創建調用非靜態成員函數的線程以完成其工作時遇到的編譯器錯誤:

#include <thread>
#include <iostream>
class Worker
{
public:
  Worker() : m_worker(&Worker::doWork, std::ref(*this), 1)
  {}
  std::thread m_worker;

  void doWork(int a) { std::cout << a << std::endl; }
};

int main(int argc, char* argv[]) {
  Worker k;
}

使用gcc4.8-gcc5.1時,由於以下原因,編譯失敗:

In file included from /usr/include/c++/4.8/thread:39:0,

from /tmp/gcc-explorer-compiler115614-69-rgangs/example.cpp:1:

/usr/include/c++/4.8/functional: In instantiation of 'struct std::_Bind_simple<std::_Mem_fn<void (Worker::*)(int)>(std::reference_wrapper<Worker>, int)>':

/usr/include/c++/4.8/thread:137:47: required from 'std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (Worker::*)(int); _Args = {std::reference_wrapper<Worker>, int}]'

7 : required from here

/usr/include/c++/4.8/functional:1697:61: error: no type named 'type' in 'class std::result_of<std::_Mem_fn<void (Worker::*)(int)>(std::reference_wrapper<Worker>, int)>'

typedef typename result_of<_Callable(_Args...)>::type result_type;

^

/usr/include/c++/4.8/functional:1727:9: error: no type named 'type' in 'class std::result_of<std::_Mem_fn<void (Worker::*)(int)>(std::reference_wrapper<Worker>, int)>'

_M_invoke(_Index_tuple<_Indices...>)

^

Compilation failed

另一方面,Clang似乎可以很好地編譯此代碼。 誰在這里是正確的,這是gcc中的錯誤(帶有公開票嗎?)?


編輯:當使用m_worker(&Worker::doWork, this, 1)初始化線程時,gcc編譯就好了。 那么,在這種情況下使用std::ref(*this)是否合法? 我想任何std::ref() ,更籠統。

您的thread構造函數調用依賴於以下語義:

[C++14: 30.3.1.2/3]: 要求: FArgs每個Ti必須滿足MoveConstructible要求。 調用 ( DECAY_COPY ( std::forward<F>(f)), DECAY_COPY (std::forward<Args>(args))...) (20.9.2)是有效的表達式。

並因此定義了INVOKE

[C++14: 20.9.2/1]:定義INVOKE (f, t1, t2, ..., tN)

  • (t1.*f)(t2, ..., tN)f是指向類T的成員函數的指針並且t1是類型T的對象或對類型T的對象的引用或對T的引用從T派生的類型的對象;
  • ((*t1).*f)(t2, ..., tN)f是指向類T的成員函數的指針並且t1不是上一項中描述的類型之一時;
  • t1.*fN == 1f是指向類T成員數據的指針,並且t1是類型T的對象或對類型T的對象的引用或對從T派生的類型的對象的引用;
  • (*t1).*fN == 1f是指向類T成員數據的指針並且t1不是上一項中所述的類型之一時;
  • 在所有其他情況下f(t1, t2, ..., tN)

如您所見,這里沒有提供std::reference_wrapper<Worker> ,這就是std::ref(*this)提供的。 當然,衰減規則中沒有任何幫助( [C++14: 30.2.6/1] )。

Clang實際上在這里稍微有點槍聲,似乎允許這樣做,因為感謝我們自己的Jonathan Wakely提交的圖書館工作組第2219期,這一天將符合標准。 但是,目前還不是。

無論如何,這整件事都沒有意義。 無需編寫此代碼。 只需寫下:

Worker() : m_worker(&Worker::doWork, this, 1)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM