16

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-id7.3.3/5 ですでに明示的に禁止されている許可、および
  • template穴にパッチを当てるのに十分な仕様がすでにあるキーワードを許可します。

この分析は正しいですか?

新しい文法が許可されていることを考えると、おそらく、を含む宣言typenameはクラス テンプレートまたはエイリアス テンプレートをインポートする必要があり、そうでない宣言typenameは関数または変数テンプレートを現在のスコープにインポートする必要があります。

     using typename derived::base::template ct;
     using derived::base::ft;

これには、追加の仕様が必要になる場合があります。また、現在の現状では、依存するテンプレート名は常にあいまいな種類 (テンプレート ID ではない) を持っているようtypenameですct

4

1 に答える 1