web-dev-qa-db-ja.com

c ++ 11のキーワードtypeof

知っている:

  • typeofはgcc拡張であり、C++標準の一部ではありません。

質問:

  1. Word typeofはC++ 11で非推奨になりましたか?言い換えれば、C++ 11を使用する場合でもgcc拡張として使用できますか?
  2. すべてのtypeofdecltypeに置き換えると、コードの動作が同じになると言うのは正しいですか?
  3. 私が_template<typename T> class wrapper_を持っていると仮定します。 _wrapper_some_field_を次と同等になるように宣言する最良の方法は何ですか:Wrapper<typeof(some_field)> wrapper_some_field
7
Hanna Khalil

Word typeofはC++ 11で非推奨になりましたか?言い換えれば、C++ 11を使用する場合でもgcc拡張として使用できますか?

非推奨ではありません。キーワードとして存在することはありませんでした。 gcc suggests _-std=c++**_でコンパイルする場合は、代わりに___typeof___を使用します。

すべてのtypeofdecltypeに置き換えると、コードの動作が同じになると言うのは正しいですか?

いいえ。たとえば、次のようになります。

_int& foo();
_

decltype(foo())は_int&_ですが、__typeof__(foo())intです。

私が_template<typename T> class wrapper_を持っていると仮定します。 [...]

wrapper<std::remove_reference_t<decltype(some_field)>> wrap{some_field}と書くこともできますが、構築関数テンプレートを書く方がクリーンです。

_template <class T> wrapper<T> make_wrapper(T const& val) { return {val}; }
auto wrap = make_wrapper(some_field);
_

または、転送あり:

_template <class T>
wrapper<std::decay_t<T>> make_wrapper(T&& val) {
    return {std::forward<T>(val)};
}
_

C++ 17では、これをまったく行わず、クラステンプレートの引数の推定を使用するだけです。

_template <class T> struct wrapper { T t; };
template <class T> wrapper(T) -> wrapper<T>;
auto wrap = wrapper{42}; // wrap is a wrapper<int>
_

また、C++ 20では、控除ガイドも必要ありません。

11
Barry
#define typeof(...) std::remove_reference_t<decltype(__VA_ARGS__)>;

ただし、タイプTのストレージを作成する場合、C++ 11で作成する方法は、std::decay_tを使用するか、状況によっては、Cスタイルを格納する独自の拡張機能を作成することです。配列をstd::arrayに。

Wrapper<std::decay_t<T>> wrapper_some_field;

Wrapperを渡したい場合は、その中に格納するのに適したタイプです。

decayは参照を削除し、関数を関数へのポインターに変換し、Tの配列をTへのポインターに変換し、その後、最上位のconstvolatileを削除します。これらは、「decay-to-pointer/value」操作の一部として関数に物事を渡すときに発生する操作と似ています。

その結果、「保管に適した」タイプになります。前述のように、int[4]std::array<int,4>に減衰することをお勧めしますが、すべてにすることはできません。