CRTP がテンプレート内で使用されている場合 (または、一般に、テンプレート パラメーターが基本クラスのテンプレート引数として渡されている場合)、using
宣言で基本のメンバー テンプレートに名前を付けることはできませんか?
template< typename d >
struct base {
template< typename >
struct ct {};
template< typename >
void ft() {}
};
template< typename x >
struct derived : base< derived< x > > {
using derived::base::template ct; // doesn't work
using derived::base::ft; // works but can't be used in a template-id
};
using-declaration文法の生成に修飾された idが組み込まれていないという理由だけで、これは言語の穴のように思えます。
using-declaration:
using typename(opt) nested-name-specifier unqualified-id ; // have this
using :: unqualified-id ;
unqualified-id:
identifier
operator-function-id
conversion-function-id
literal-operator-id
~ class-name
~ decltype-specifier
template-id
qualified-id:
nested-name-specifier template(opt) unqualified-id // want this
:: identifier
:: operator-function-id
:: literal-operator-id
:: template-id
唯一のルールがusing-declaration: using typename(opt) qualified-id
である場合、唯一の結果は
- 意味をなさない 、、およびを除外し
:: conversion-function-id
、:: ~ class-name
:: ~ decltype-specifier template-id
:: template-id
7.3.3/5 ですでに明示的に禁止されている許可、およびtemplate
穴にパッチを当てるのに十分な仕様がすでにあるキーワードを許可します。
この分析は正しいですか?
新しい文法が許可されていることを考えると、おそらく、を含む宣言typename
はクラス テンプレートまたはエイリアス テンプレートをインポートする必要があり、そうでない宣言typename
は関数または変数テンプレートを現在のスコープにインポートする必要があります。
using typename derived::base::template ct;
using derived::base::ft;
これには、追加の仕様が必要になる場合があります。また、現在の現状では、依存するテンプレート名は常にあいまいな種類 (テンプレート ID ではない) を持っているようtypename
ですct
。