C++11標準ライブラリのスレッドサポートライブラリ定義で用いられるDECAY_COPY関数に関するメモ*1。
2021-10-21追記:C++2b(C++23)に向けた提案文書 P0849R8 が採択され、decay-copy動作を行う明示型変換(explicit type conversion)式auto(t), auto{t}が言語仕様に追加される。
大雑把に、DECAY_COPY(t)の結果はauto x = t;と代入した変数xに相当する*2。
tが型Tのrvalueの場合はxはムーブされた型Tオブジェクト。それ以外ならxはコピーされた型Tオブジェクトとなる。tが配列型の場合、xは先頭要素へのポインタとなる。(4.2 Array-to-pointer conversion相当)tが関数型の場合、xは関数へのポインタとなる。(4.3 Function-to-pointer conversion相当)
DECAY_COPYは下記の Effects 定義において、INVOKE( DECAY_COPY(std::forward<F>(f)), DECAY_COPY(std::forward<Args>(args))...)のように利用されている。動作イメージとしては「ファンクタfに、コピー/ムーブした実引数群arg...を指定して呼び出す」となる*3。このため、引数を参照として渡す場合はstd::refを利用する必要がある。
// threadコンストラクタ(30.3.1.2) template <class F, class ...Args> explicit thread(F&& f, Args&&... args); // call_once関数(30.4.4.2) template<class Callable, class ...Args> void call_once(once_flag& flag, Callable&& func, Args&&... args); // async関数(30.6.8) template <class F, class... Args> future<〜> async(F&& f, Args&&... args); template <class F, class... Args> future<〜> async(launch policy, F&& f, Args&&... args);
N3337 30.2.6/p1より引用。
In several places in this Clause the operation DECAY_COPY(x) is used. All such uses mean call the function
decay_copy(x)and use the result, wheredecay_copyis defined as follows:template <class T> typename decay<T>::type decay_copy(T&& v) { return std::forward<T>(v); }
関連URL