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_copy
is defined as follows:template <class T> typename decay<T>::type decay_copy(T&& v) { return std::forward<T>(v); }
関連URL