pack 引数は、エイリアス テンプレートの pack パラメータの場所でのみ展開できるようです。これは、クラスまたは関数テンプレートには当てはまりません。
template <class T, class... Args> struct x { using type = T; };
template <class T, class... Args> using x_t = typename x<T, Args...>::type;
template <class... Args> using x_fix_t = typename x<Args...>::type;
template <class... Args> auto f(Args...) -> void {
typename x<Args...>::type v1; // OK
x_t<Args...> v2; // Error
x_fix_t<Args...> v3; // OK
}
より単純なケース:
template <class T, class U> using y_t = T;
template <class... Args> auto f(Args...) -> void {
y_t<Args...> v4; // Error
}
上記のコードは、とin 、とf
の両方で ( がインスタンス化されていなくても)エラーを生成します。c++11
c++14
g++ 4.9
g++ 5.1
clang 3.5
これが許可されない理由と一般的なルールは何ですか? これを制限する理由はありません。それは非常に奇妙な禁止のようです。
x_fix_t
最初のバリアントのように書かない理由についてx_t
は、必須の最初の引数があることがより明確です。(たとえば、それがf()
許可されていない理由です)。しかし、これはそれほど重要ではありません。修正は簡単です。疑問が残ります:なぜですか?
gcc エラー:
error: pack expansion argument for non-pack parameter ‘T’ of
alias template ‘template<class T, class ... Args> using x_t = typename x::type’
クランエラー:
error: pack expansion used as argument for non-pack parameter of
alias template x_t<Args...> v2;