1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

C++11, C++14 でも std::visit でパターンマッチングしたいメモ

Last updated at Posted at 2021-08-23

背景

std::visit + overloaded(パターンマッチング)便利ですよね.

C++11, C++14 でもやりたいですね!

C++14 以下で std::variant の実装は variant-lite があります.

overloaded テンプレートについては, using Ts::operator()...; は C++17 の構文なので, C++11, C++14 でやるとコンパイルエラーになります.

で C++11, C++14 でやる方法ありました!

template <class... Fs> struct overload_set;

template <class F1, class... Fs>
struct overload_set<F1, Fs...> : F1, overload_set<Fs...>::type
{
    typedef overload_set type;

    overload_set(F1 head, Fs... tail)
        : F1(head), overload_set<Fs...>::type(tail...)
    {}

    using F1::operator();
    using overload_set<Fs...>::type::operator();
};

template <class F>
struct overload_set<F> : F
{
    typedef F type;
    using F::operator();
};

template <class... Fs>
//auto overload(Fs... x) for C++14
typename overload_set<Fs...>::type overload(Fs... x)
{
    return overload_set<Fs...>(x...);
}

nonstd::variant<int, float, std::string> Var;

Var v = 2;

std::string ty =  nonstd::visit(overload (
          [](auto) { return "[[TODO]]"; },
          [](int) { return "int"; }
), v);

std::cout << ty;

Voila!

C++11 だと取り得る型は全部記述する必要がありますのでちょっとめんどいです.

C++14 だと, マッチしなかったのは auto にしたのに fallback してくれます(ただし, float -> double などの implicit cast に注意! )

その他

mapbox variant では .match があります.

ただインターフェイスが std::variant とは異るので使いづらいときもあります.
(将来的に C++17 に移行するときに書き直しが必要)

問題

やっぱりそこそこコンパイルに時間かかるようになってしまいます...

TODO

  • C++14 にもなると auto とか ... の嵐でテンプレートの仕組みがよくわからなくなりつらい(デバッグがめんどい)ので理解する
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?