1

私は(haskellで)おおよそ次のようなメタ関数を書こうとしています:

gather :: [a] -> [a] -> ([a], [a])
gather (x:xs) (_:_:ys) = <something using x, xs, and ys>
...other pattern matches...

私は独自の独自の可変個引数テンプレート シーケンスを使用してこれを行うことができましたが、mpl を使用してこれを行う方法を理解できないようです。

簡単にするために、このサンプル関数を試していました(必要なものを理解するのに役立つはずです):

//get_first :: [a] -> a
template<class SEQ_C>
get_first { 
    enum { value = -1 }; 
    typedef get_first<SEQ_C> type;
}; 

//get_first (x:xs) = x
template<template<class T, T... S> class SEQ_C, class T, T x, T... xs>
struct get_first<SEQ_C<T, x, xs...>> {
    enum { value = x };
    typedef get_first<SEQ_C<T, x, xs...>> type;
};

...

typedef boost::mpl::vector_c<int 1, 2, 3> listA;
typedef get_first<listA>::type first;
std::cout << first::value << std::endl;

-1 を出力します。

私はこの時点で一致を得るためにさまざまな方法を試しましたが、暗闇の中で刺すだけです. mpl::vector_c<int, x>ドキュメントでは、実際にはリストのように見えますがintegral_c<int, x>、この結果を使用しようとすると、他のエラーが発生します。

多分パターンマッチング

4

2 に答える 2

2

うわー、私は問題の根本を見つけます。エラーメッセージを見てください(typedef get_first<SEQ_C> type;行にコメントすると表示されます):

error: ‘type’ in ‘struct get_first<boost::mpl::vector_c<int, 1l, 2l, 3l> >’ does not name a type
//                                                            ^   ^   ^

ご覧のとおり、は渡された引数をではなく としてg++解釈します。したがって、仕様を次のように変更すると:longint

template<template<class T, long... S> class SEQ_C, class T, long x, long... xs>
struct get_first<SEQ_C<T, x, xs...>> {
    enum { value = x };
    typedef get_first<SEQ_C<T, x, xs...>> type;
};

それはうまくいくでしょう。

もちろん、これは解決策ではなく、どのように機能するかを示すだけです。clang ++が1コード用に生成するため、g ++のバグだと思います。

于 2013-06-26T18:20:02.643 に答える