从基本的C ++ CRTP和访问来源的嵌套的typedef [英] C++ CRTP and accessing derived's nested typedefs from base

查看:155
本文介绍了从基本的C ++ CRTP和访问来源的嵌套的typedef的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑:我在这里放了GitHub的链接时,我做了我的改变设计的人谁是有兴趣

edit: I'll put a github link here when I am done altering my design for anyone who is interested.

背景

我更换的boost ::侵入 intrusive_set ,用我自己的实现作为64位编译侵入集充塞3×8字节指针到我的容器节点。我的容器有2 ^ 16个节点的限制,所以我可以用2个16位偏移序数(这是大小的6倍降低)把它归结为每个节点4个字节。

I'm replacing a boost::intrusive, intrusive_set, with my own implementation as 64-bit compiled intrusive-set stuffs 3 x 8-byte pointers into my container nodes. my container has a limit of 2^16 nodes so I can bring it down to 4-bytes per node with 2x 16-bit offset ordinals (which is a 6x reduction of size).

在下面基地的例子是侵入集容器。在导出类有一个的std ::矢量<&container_entry_type LT;条目类型> > 。显然这种级别的间接我需要在衍生一堆嵌套的typedef的,我想指的基地,

In the example below base is the intrusive-set container. The derived class has a std::vector<container_entry_type<entry_type> >. obviously with this level of indirection I need to have a bunch of nested typedef's in derived, which I'd like to refer to in base.

P.S。,容器是用于数据描述语言的AST。因此所含的元素是小的数据类型和3×8个字节是非常显著。尤其是如此以来,集装箱被用来在密集的循环验证数据集。

p.s., the containers are for the AST of data description language. The contained elements are therefore small data types and 3 x 8-bytes is very significant. Especially so since the containers are used to validate data-sets in tight loops.

问题隔离

我要实现以下语义:

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。这就是铛不得不说这件事:

But I can't access the nested typedef from the base. This is what clang has to say about the matter:

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>’

相反,我有做的:

Instead I am having to do:

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;
}

这是实现我的用例的唯一途径?它只是使事情一大堆更详细。我猜想衍生还可以从特质得到节省一些按键。

Is this the only way to achieve my use-case ? it just makes things a whole lot more verbose. I suppose derived could also derive from traits to save some keystrokes.

另一种选择是不使用推导和逻辑直接连线到什么是当前的。不过,我想单独单元测试基地。

Another choice is to not use derivation and to wire the logic straight into what is currently derived. However, I'd like to individually unit test base.

推荐答案

另一种可能性(即可能或不可能救你的击键)将在一些地方父不使用派生类嵌套类型可以。例如。而不是

Another possibility (that might or might not save you keystrokes) would be not using the derived classes' nested types in the parent in some places. Eg. instead of

void foo(typename TWO::dummy & d);

你会使用

template <class T>
void foo(typename T& d);

有关加分,你可以使用SFINAE实际限制 T 的类型允许原变种。 (请注意这里面嵌套模板,二::虚拟可以自由使用 - 他们只是实例化的之后的整个事情包括<$ C $。 C>导出一直,所以它的作品了,在天真的版本,导出仍处于实例化<$ C $点不全C>基及其成员函数,它没有 ::虚拟,这就是为什么它失败)

For extra points, you could use SFINAE to actually limit T to the types permissible for the original variant. (Note that inside nested templates, TWO::dummy can be used freely - they are only instantiated after the whole thing incl. derived has been, so it works out. In the naive version, derived is still incomplete at the point of instantiating the base with its member functions, it has no ::dummy, which is why it fails)

这篇关于从基本的C ++ CRTP和访问来源的嵌套的typedef的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆