編集:興味のある人のためにデザインの変更が完了したら、ここに github リンクを配置します。
バックグラウンド
boost::intrusive
, , を独自の実装に置き換えます。これはintrusive_set
、64 ビットでコンパイルされた侵入セットがコンテナー ノードに 3 x 8 バイトのポインターを詰め込むためです。私のコンテナーには 2^16 ノードの制限があるため、2x 16 ビットのオフセット序数 (サイズの 6 倍の縮小) を使用して、ノードあたり 4 バイトまで下げることができます。
以下の例base
は、侵入セット コンテナーです。derived
クラスにはstd::vector<container_entry_type<entry_type> >
. 明らかに、このレベルの間接化では、ネストされた typedef を派生に含める必要があります。これをベースで参照したいと思います。
ps、コンテナーはデータ記述言語の AST 用です。したがって、含まれる要素は小さなデータ型であり、3 x 8 バイトは非常に重要です。コンテナーはタイトなループでデータセットを検証するために使用されるため、特にそうです。
分離された問題
次のセマンティクスを実現したい:
template<typename TWO>
class base
{
public:
void foo(typename TWO::dummy & d);
};
template<typename DUMMY>
class derived
: private base< derived<DUMMY> >
{
public:
typedef DUMMY dummy;
};
struct tag{};
int main()
{
derived<tag> foo;
}
しかし、ネストされた typedef にベースからアクセスできません。この問題について、clang は次のように述べています。
main.cc: In instantiation of ‘base<derived<tag> >’:
main.cc:9:7: instantiated from ‘derived<tag>’
main.cc:20:16: instantiated from here
main.cc:5:8: error: no type named ‘dummy’ in ‘class derived<tag>’
代わりに、私はしなければなりません:
template<typename type_key>
class traits
{
public:
typedef type_key dummy;
};
template<typename TWO, typename type_key>
class base
{
public:
void foo(typename traits<type_key>::dummy & d);
};
template<typename DUMMY>
class derived
: private base< derived<DUMMY>, DUMMY >
{
public:
typedef DUMMY dummy;
};
struct tag{};
int main()
{
derived<tag> foo;
}
これが私のユースケースを達成する唯一の方法ですか? 物事がずっと冗長になるだけです。派生は、いくつかのキーストロークを節約するために特性から派生することもできると思います。
もう 1 つの選択肢は、派生を使用せず、現在派生されているものにロジックを直接接続することです。ただし、個別にテストベースを単体テストしたいと思います。