C++

[C++17]ほしい要素だけ構造化束縛したい

  • このエントリーをはてなブックマークに追加
  • Pocket

この記事の発端

Twitterでこんな会話を目撃したこと。 しばらくあとにコードが投下される。 このコード、要素をコピーしとるやんけ。 forwarded tupleで返さんかい! そう思った僕は、たいして重くもない腰を上げてキーボードを叩き始めた。

実装

std::forward_as_tuple(std::get<I>(t)...) を返すようにする。 簡単に実装すると以下のようになる(これで十分動作する)。
namespace mitama {
template <std::size_t... Indices>
auto select = [](auto&& tup) {
    return std::forward_as_tuple(std::get<Indices>(tup)...);
};
}
なんのSFINAEもないautoという引数を持つうえ、selectというジェネリックすぎる名前を持っているが、まあ気にしないことにしよう(なんならindex out of rangeもstd::getに丸投げしとる)。
このコードは以下のように使うことができる。
int main(){
    auto tuple_print = [](auto&&... e){
        ((void)(std::cout << e << ' '), ...);
        std::cout << std::endl;
    };
    using namespace std::string_literals;
    std::tuple t = {12, 32, "abc"s};
    auto [a, c] = mitama::select<0, 2>(t);
    std::cout << a << ' ' << c <<std::endl;
    // 12 abc
    a = 6;
    std::apply(tuple_print, t);
    // 6 32 abc    
}
参照でtupleの中身を取得できるので当然書き換えるともとのタプルの要素を書き換えることができる。 ついでにselect_as_constでも作っておこうか。
template <std::size_t... Indices>
auto select_as_const = [](auto&& tup) {
    return std::forward_as_tuple(std::as_const(std::get<Indices>(tup))...);
};
int main(){
    using namespace std::string_literals;
    std::tuple t = {12, 32, "abc"s};
    auto [a, c] = mitama::select_as_const<0, 2>(t);
    a = 6; // error! cannot assign to variable 'a' with const-qualified type
}
本当はもうちょっとちゃんと作ったほうがいいのかもしれないけど、飽きもうした。 Wandboxのリンクでも貼って終わりにするか。 おわりおわり。
ところで、今日は誕生日なんで、欲しい物リストも貼っておくね。
  • このエントリーをはてなブックマークに追加
  • Pocket

コメントを残す

*

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください