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宣言文法の生産は資格-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
た場合は、唯一の結果は
- は
:: ~ class-name
、:: conversion-function-id
を除外されるだろう、と何の意味論的な意味を成さない:: ~ 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
に属していることは明らかではありません。
興味深い分析です。特定された「穴」が抑止されるような方法で*これを使用する場所が不思議です。私。これがプログラムのアーキテクチャを取り返して再検討しなければならないロードブロッキングである現実のアプリケーションとは何ですか? – WhozCraig
@WhozCraigこれは、テンプレートからCRTPを使用するたびに表示されます。基本クラスは、使用するたびに 'this - > * template'または' base :: template'と言うべきインタフェースを提供します。 – Potatoswatter
さて、私はそれを得ると思います。この特殊なケースは、 'using'節でそれを使って人生を楽にすることですが、許可されていないようです。良い例え。ありがとうございました。 – WhozCraig