私は現在、boost::mpl::apply のような式を評価するためのメタ関数を書いています。
template<typename EXPRESSION , typename... ARGS>
using eval = typename eval_impl<EXPRESSION,ARGS...>::result;
ご覧のとおりtypename ::result
、エバリュエーターを使用する際の書き込みを避けるために、C++11 テンプレート エイリアスを使用しています。
他の特殊化の中でも、eval_impl
(評価メタ関数の実装) には、ユーザーがパラメーター化された式 (メタ関数など) とパラメーターのセットを渡す場合の特殊化があります。つまり、eval
指定されたパラメーターのセットでメタ関数を評価するための高次メタ関数として使用します。
その場合、私は次のように専門化を書きました。
template<template<typename...> class F , typename... PLACEHOLDERS , typename... ARGS>
struct eval_impl<F<PLACEHOLDERS...>,ARGS...> : public F<ARGS...> {}
ここでユースケースを考えてみましょう:
template<typename ARG , typename... ARGS> using first_of = ARG;
using call = eval<first_of<_1,_2,_3,_4> , bool,float,char,int>;
ここでは、カスタム メタ関数をテンプレート エイリアスとして定義し、 呼び出し (評価) に使用する一連のパラメーターと共にfirst_of
に渡します。、... は単なるプレースホルダーです。eval
_1
_2
上記で定義された特殊化のインスタンスを呼び出すことを期待してeval
いましたが、そうではありません。また、エイリアス化された型が型自体ではなく、1 つのパラメーターのテンプレートである場合、GCC 4.8.1 は次のように述べています。
エラー: 1 つのテンプレート パラメーターが必要ですが、2 つ指定されました
そのeval_impl
専門化のインスタンス化の時点で。
エラーにより、テンプレート エイリアスが部分特殊化のテンプレート テンプレート パラメータに取り込まれず、代わりにエイリアス化された型が一致すると考えられます。
例でわかるように、それは私が望まないことではありません。テンプレート エイリアスを他のメタ関数と一致させる必要があります。それを達成する方法はありますか?