[解決済み] std::getはどのように動作するのですか?
質問
を作ろうとした結果
std::get<N>
<サブ
(std::tuple)
というメソッドが、コンパイラによってどのように実装されているのか、私自身はあまりよく分かっていません。私が知っているのは
std::tuple
には、このようなコンストラクタがあります。
tuple(Args&&... args);
しかし、具体的にどのような
args...
が割り当てられているのでしょうか?を知るために役立つと思います。
std::get
は、引数をアクセスするためにどこかに配置する必要があるため、動作します...。
どのように解決するのですか?
以下は
tuple
-のようなクラスです。
まず、整数の列を表現するためのメタプログラミングの定型文をいくつか紹介します。
template<int...> struct seq {};
template<int max, int... s> struct make_seq:make_seq< max-1, max-1, s... > {};
template<int... s> struct make_seq<0, s...> {
typedef seq<s...> type;
};
template<int max> using MakeSeq = typename make_seq<max>::type;
次に、実際にデータを格納するタグ付きクラスです。
template<int x, typename Arg>
struct foo_storage {
Arg data;
};
このタグ付けの手法は、コンパイル時にデータを何らかのタグ(この場合は整数)と関連付けたいときによく使われるパターンです。 このタグ(
int
ここでは)通常、ストレージのどこにも使用されません。
foo_helper
は、シーケンスと引数のセットを、複数の
foo_storage
そして、それらを線形に継承します。 これはよくあるパターンで、これをたくさんやっていると、結局これをやってくれるメタプログラミングのツールを作ることになります。
template<typename Seq, typename... Args>
struct foo_helper {};
template<int s0, int... s, typename A0, typename... Args>
struct foo_helper<seq<s0, s...>, A0, Args...>:
foo_storage<s0, A0>,
foo_helper<seq<s...>, Args...>
{};
私の粗悪品
tuple
の型があります。
foo
で、一連のインデックスと引数からなるパッケージを作成し、 上記のヘルパーに渡します。 そして、ヘルパーは親クラスを保持するタグ付きデータの束を作成します。
template<typename... Args>
struct foo: foo_helper< MakeSeq<sizeof...(Args)>, Args... > {};
の本文からすべてを削除しました。
foo
を実装するのに必要ないからです。
get
.
get
は非常にシンプルです。タプル型ではなくストレージ型をとり、明示的に
template
引数
N
がどのようなものであるかを曖昧にします。
foo_storage<n, T>
にアクセスすることになります。 ストレージの型がわかったので、あとはデータフィールドを返すだけです。
template<int N, typename T>
T& get( foo_storage<N, T>& f )
{ return f.data; }
template<int N, typename T>
T const& get( foo_storage<N, T> const& f )
{ return f.data; }
C++言語のオーバーロード機構を利用して、重い仕事をこなしているのです。 あるクラスのインスタンスで関数を呼び出すと、そのインスタンスと親クラスのそれぞれを調べて、一致させることができるかどうかを確認します。 このとき
N
が固定されている場合、有効な引数となる親クラスは1つだけなので、親クラス(つまりは
T
が自動的に推論されます。
そして最後に、基本的なテストコードをいくつか紹介します。
#include <iostream>
int main() {
foo<int, double> f;
get<0>( f ) = 7;
get<1>( f ) = 3.14;
std::cout << get<0>(f) << "," << get<1>(f) << "\n";
}
関連
-
[解決済み] error: 'if' の前に unqualified-id を期待した。
-
[解決済み】エラー:不完全な型へのメンバーアクセス:前方宣言の
-
[解決済み] explicit キーワードの意味は?
-
[解決済み] 文字列の単語を反復処理するにはどうすればよいですか?
-
[解決済み] using namespace std;」はなぜバッドプラクティスだと言われるのですか?
-
[解決済み] 1ビットのセット、クリア、トグルはどのように行うのですか?
-
[解決済み] C++11では、標準化されたメモリモデルが導入されました。その意味するところは?そして、C++プログラミングにどのような影響を与えるのでしょうか?
-
[解決済み] std::move()とは何ですか?また、どのような場合に使用するのですか?
-
[解決済み] const std::string & をパラメータとして渡す時代は終わったのでしょうか?
-
[解決済み] Intel CPU の _mm_popcnt_u64 で、32 ビットのループカウンターを 64 ビットに置き換えると、パフォーマンスが著しく低下します。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】 unsigned int vs. size_t
-
[解決済み】C++コンパイルタイムエラー:数値定数の前に期待される識別子
-
[解決済み】文字列関数で'char const*'のインスタンスを投げた後に呼び出されるterminate [閉店].
-
[解決済み】IntelliSense:オブジェクトに、メンバー関数と互換性のない型修飾子がある
-
[解決済み】浮動小数点例外エラーが発生する: 8
-
[解決済み】Visual C++で "Debug Assertion failed "の原因となる行を見つける。
-
[解決済み】C++の余分な資格エラー
-
[解決済み】エラー:free(): 次のサイズが無効です(fast)。
-
[解決済み】浮動小数点数の乱数生成
-
[解決済み】Eclipse IDEでC++エラー「nullptrはこのスコープで宣言されていません」が発生する件