2017-12-18 8 views
5
C++で

テンプレートメタプログラミング、私は多くの場合、次のように実行します。違い::崩壊とstd :: remove_reference

template <typename T> 
S<T> make_wrapper(T&& t) { return S<T>(std::forward<T>(t)); } 

私は戻り値の型にstd::decayのようなものを使用する必要があります知っているが、なぜstd::remove_referenceもうまくいかないでしょうか?ここでの違いは何ですか? std::remove_cvrefはどうですか?

+5

「Tが何であるかに応じて、より多くのことができます」(http://en.cppreference.com/w/cpp/types/decay) –

+5

あなたはそれらについて読んだことがありますか?たとえば、[この 'std :: decay'リファレンス](http://en.cppreference.com/w/cpp/types/decay)と[この' std :: remove_reference'リファレンス](http://en.cppreference .com/w/cpp/types/remove_reference)。 –

答えて

4

参照を削除すると、constvolatileのままになります。それがあなたの望むものなら、それで十分です。

decayはほとんどの場合cvrefを削除しますが、関数型と配列型はポインタに変換されません。

崩壊は、配列のコピーを配列またはstructに合理的に格納できるように型を変換するか、関数から返すか関数に渡します。

8

#include <type_traits> 

int main() 
{ 
    static_assert(std::is_same_v< 
     std::decay_t<const int&>, 
     std::remove_reference_t<const int&> 
    >); // int != const int 
} 

std::decay例えば考えてみてはremove_referenceはないでしょう、任意のCV-修飾子を削除します。これは、型の "参照"部分を削除するだけです。 referenceから

は、型Tに左辺ツー右辺、アレイへのポインタ、および機能へのポインタ 暗黙の変換を適用し、CV-修飾子を除去し、 定義結果の型をメンバ型のtypedef型として返します。

したがって、std::decayは、std::remove_referenceよりも多くの型変換を実行します。

remove_volatile

のみ、remove_cvなど、または、C++ 20、remove_cvrefでないdecay可能な変換のセットの選択された部分を実行するより微妙なアプリケーションのためのさらなるタイプ修飾子もあります。

+0

'std :: remove_cvref'は十分ですか? –

+1

@Nex ':いいえ、[docs](http://en.cppreference.com/w/cpp/types/decay)を読むのに実際には2分しかかかりません。 –

+0

@Nex 'おそらく、あなたは 'std :: invoke'の使用を考慮する必要があります。 – Jodocus