【发布时间】:2015-10-26 02:50:20
【问题描述】:
我想使用模板的枚举参数来限制第二个参数,一个类,反过来将枚举的成员作为参数作为模板参数。在代码中,我希望它看起来像:
CObject<EObjectTag, CSubObject<EObjectTag::CAT_A>> cObject;
这应该可以,但是:
CObject<EObjectTag, CSubObject<ENotAnObjectTag::CAT_OTHER>> cObject;
应该失败,因为ENotAnObjectTag::CAT_OTHER 不是EObjectTag 的元素。
我的实现(尝试)如下,并在编译期间(在 gcc 版本 4.9.2(Ubuntu 4.9.2-10ubuntu13)上)出现错误消息:
source.cc:16:45:错误:“SUBOBJECT_TAG”未在此范围内声明 结构 CObject>
#include <iostream>
#include <typeinfo>
enum class EObjectTag {CAT_A, CAT_B, CAT_OTHER};
// CSubObject
template<class OBJECT_TAG_T, OBJECT_TAG_T OBJECT_TAG>
struct CSubObject { OBJECT_TAG_T m_tTag = OBJECT_TAG; };
// CObject - Forward declaration
template <class SUBOBJECT_TAG_T, template <SUBOBJECT_TAG_T SUBOBJECT_TAG> class SUBOBJECT_T>
struct CObject;
// CObject - Specialization
template <class SUBOBJECT_TAG_T, template <SUBOBJECT_TAG_T SUBOBJECT_TAG> class SUBOBJECT_T>
struct CObject<SUBOBJECT_T<SUBOBJECT_TAG_T, SUBOBJECT_TAG>>
{
public:
SUBOBJECT_T<SUBOBJECT_TAG_T, SUBOBJECT_TAG> m_cSubObject;
};
int main() {
// The aim is that the second object only accepts a tag that
// belongs to EObjectTag
CObject<EObjectTag, CSubObject<EObjectTag::CAT_A>> cObject;
return 0;
}
最后一个用例涉及将 CSubObject 替换为 CObject,以便我们可以使用递归来定义标记对象的层次结构,这也需要使用可变参数模板来在同一级别拥有多个对象。例如:
/* EBase, */
CObject</*EBase::BASE,*/ EObject,
CObject<EObject::INIT, EInitObject,
CObject<EInitObject::INIT_FOO>,
CObject<EInitObject::INIT_BAR>,
>,
CObject<EObject::COUNT, ECountObject,
CObject<ECountObject::COUNT_FOO>,
CObject<ECountObject::COUNT_BAR>,
>,
> cMyObjectHierarchy;
注释掉的对 EBase(库内部的枚举)的引用是为了保持 CObject 的模板参数一致,我会计划(如果可能)通过模板特化或默认参数自动执行此操作。
我指定此对象层次结构的目标还包括:
- 避免强制此库的用户定义其他类 或他们程序中的结构
- 利用编译时间检查通过 使用枚举对 CObject 进行模板化,其函数又使用该枚举 枚举作为所有 CObject 共有的一组函数的参数
【问题讨论】:
-
请描述清楚的问题陈述或问题。你有不明确的目标(尽可能利用编译时检查等),但没有什么明确。我可以(并且已经)描述了您的代码的无数问题,但这并不能让我们接近解决您的实际问题,因为您的实际问题尚不清楚。您似乎有一个目标,并且您生成了一堆无法解决它的代码,但这并没有传达您的目标是什么。
-
@Yakk 感谢您的反馈,我已经更新了问题第一部分的措辞并删除了最后一部分,因为它与我的问题确实相关。
标签: c++ templates c++11 enums template-templates