読者です 読者をやめる 読者になる 読者になる

C++14ラムダでの< > テンプレート?

さきほどqiitaに書いた記事、

qiita.com

C++ラムダ式に言及したのだが、よくわからなくなった。

まず、

[]<typename T>(T const& a, std::vector<std::vector<T>> const& b){
    auto tmp = b;
    for ( auto& i : tmp )    i.insert(i.begin(), a);
    tmp.insert(tmp.begin(), std::vector<T>{1, a});
    return tmp;
};

というラムダ式gccコンパイルできた。(C++14指定) http://melpon.org/wandbox/permlink/04WzozqwuAerr0Ps

しかしコンパイラの指定をclangにするとこのようにエラーになる。

f:id:mmYYmmdd:20151003095522j:plain

まずこの理由がわからない。< と > で囲んだテンプレート表現自体が使えないかのようなメッセージだ。

次に、コンテナを抽象化できないかと思って template template パラメータを試してみた。

   auto lm = []<typename T, template <typename> class V>(T&& a, V<V<std::decay_t<T>>> const& b) {
        auto tmp = b;
        for ( auto& i : tmp )    i.insert(i.begin(), a);
        tmp.insert(tmp.begin(), V<std::decay_t<T>>{1, a});
        return tmp;
    };

これはgccでもclangでも長いエラーメッセージが出てダメだった。 もしや、と思って次のようにしてみたがやっぱりダメだった。

   auto lm = []<typename T, template <typename> class V1, template <typename> class V2>(T&& a, V1<V2<std::decay_t<T>>> const& b) {
        auto tmp = b;
        for ( auto& i : tmp )    i.insert(i.begin(), a);
        tmp.insert(tmp.begin(), V2<std::decay_t<T>>{1, a});
        return tmp;
    };

次のように auto だけ使っていればどちらでもOK。

    auto lm = [](auto&& a, auto&& b) {
        auto tmp = b;
        for ( auto& i : tmp )    i.insert(i.begin(), a);
        using V = std::decay_t<decltype(*tmp.begin())>;
        tmp.insert(tmp.begin(), V{1, a});
        return tmp;
    };

気力がなくなってきた。