CRTP子类和实例列表
我正在尝试实现一种具有多重继承的 CRTP(如果我很好地理解它是什么)。
我的主要目标是有一个统一的方式来访问每个子类的实例列表。
可能的问题似乎在于命名空间的利用率。
这是最简单版本的代码: http://ideone.com/rFab5
我真正的问题更类似于: http://ideone.com/U7cAf
我使用 clang++ 时收到一个附加警告:
test.cpp:28:63: warning: static data member specialization of 'instances' must originally be declared in namespace 'NS1'; accepted as a C++0x extension [-Wc++0x-extensions]
template <> std::list<NS1::Derived*> NS1::Base<NS1::Derived>::instances;
^
test.cpp:15:34: note: explicitly specialized declaration is here
static std::list<T*> instances;
问题已更新使用命名空间时它的行为不同。
问题已重新编辑以在 Ideone 上发布代码
I'm trying to implement a kind of CRTP (if I well understand what it is) with multiple inheritance.
My main goal is to have a unified way to access list of instances of each subclass.
May problem seems to reside in the namespace utilization.
Here is the code of the simplest version :
http://ideone.com/rFab5
My real problem is more similar to :
http://ideone.com/U7cAf
I have an additional warning using clang++ :
test.cpp:28:63: warning: static data member specialization of 'instances' must originally be declared in namespace 'NS1'; accepted as a C++0x extension [-Wc++0x-extensions]
template <> std::list<NS1::Derived*> NS1::Base<NS1::Derived>::instances;
^
test.cpp:15:34: note: explicitly specialized declaration is here
static std::list<T*> instances;
Problem has been updated since it does not behave the same using namespaces.
Problem re-edited to post code on Ideone
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
问题是您尝试错误地定义列表变量。一般来说,您需要为 Base 提供一个定义 - 您不仅仅为恰好是 Derived 子类的一部分定义它,除非它是显式专业化。
http://ideone.com/Vclac
编译没有错误。不需要任何中间体或类似的东西。
The problem is that you've tried to define the list variable wrong. You need to provide a definition for Base, in general- you don't just define it for the one part that happens to be Derived's subclass, unless it's an explicit specialization.
http://ideone.com/Vclac
Compiles with no errors. There are no intermediates or anything like that required.
将
Base()
和Intermediary()
更改为Base()
和Intermediary
构造函数使代码对于 GCC 来说OK。在第二种情况下没有理由更改实例的定义:模板与第一种情况相同。
Changing
Base()
andIntermediary()
toBase<U>()
andIntermediary<Derived>
in the constructors makes the code OK for GCC.There is no reason to change the definition of
instances
in the second case: the template is identical as the first situation.Afaik,您有以下选择。
首先,如果
Intermediate
始终在派生类型上进行模板化,则不需要它的列表,因为它永远不会是最派生的类型。如果它可以在其他类型上模板化/不派生,您可以添加一个默认的非类型 bool 模板参数,如下所示:如果中间类未模板化并且尚未从
Base
派生,则您需要在最派生的类中再次从Base
派生:当中间体也从
Base
派生但未模板化时,就会出现大问题。您可以添加默认的派生类型,但这会使非派生使用变得更加难看:Afaik, you got the following options.
First, if
Intermediate
is always templated on the derived type, you don't need a list for it, because it will never be the most derived type. If it could be templated on other types / not be derived, you can add a defaulted non-type bool template parameter like so:If the intermediate class is not templated and does not already derive from
Base
, you need to derive fromBase
again in the most derived class:The big problem comes when the intermediate also derives from
Base
but is not templated. You can add a defaulted derived type, but that would make the non-derived use a bit more ugly:以下内容可以在 MinGW g++ 4.4.1、MSVC 10.0 和 Comeau Online 4.3.10.1 上编译正常:
instances
定义是从您的问题中逐字复制的。我说,作为艾萨克·牛顿,我不提出任何假设!
干杯&呵呵,
The following compiles OK with MinGW g++ 4.4.1, MSVC 10.0, and Comeau Online 4.3.10.1:
The
instances
definition is copied verbatim from your question.I say as Isaac Newton, I frame no hypotheses!
Cheers & hth.,