带有继承列表的 C++ 模板声明

C++ template declaration with inheritance list

是否可以在 C++ 中声明一个模板化的 class 以及它继承自的 classes?基本上我想给编译器一个提示,我的模板 class 将始终在声明时继承另一个。 也许一些代码会弄清楚为什么这对我来说是个问题:

template<typename T>
class GrandparentClass
{
public:
    T grandparentMember;
};

//this needs to be only a declaration, since I do not want classes of ParentClass with random T
template<typename T>
class ParentClass : public GrandparentClass<T>
{

};

// this does not work:
//template<typename T>
//class ParentClass : public GrandparentClass<T>;

// this does not either, because then the child class cannot access the variable from the grandparent class
//template<typename T>
//class ParentClass;

template<>
class ParentClass<int> : public GrandparentClass<int>
{
public:
    ParentClass()
    {
        grandparentMember = 5;
    }
};

template <typename T>
class ChildClass : public ParentClass<T>
{
public:
    void foo()
    {
        std::cout << grandparentMember << "\n";
    }
};

此外,我无法使用 C++ 11。

编辑:

我找到了解决此问题的简单方法:

template<typename T>
class ParentClass : public GrandparentClass<T>
{
public:
    ParentClass() { ParentClass::CompilerError(); };
};

只是不要在 class 中定义 CompilerError() 方法,一切都很好。

A class 声明仅对非值变量声明真正有用,例如指针和引用。但是,您无法访问 class 成员,甚至无法实例化它。即使您知道声明的 class 继承自其他某个声明,您仍然不一定能够以任何方式利用该信息。

因此,对于编译器来说,了解 class 的完整定义后,了解它继承自什么才是重要的。


在评论中澄清后:如果你想阻止 实例化 具有某些类型的 class 模板,它的定义就是这样做的地方。 class 体内的一个简单的 static_assert 就可以解决问题; Boost.StaticAssert 或更早的 SFINAE 技巧将完成 C++11 之前的代码的工作。

如果您愿意将错误延迟到 link 时间,而不是编译时间,您可以在 parent.h 中声明 parent 的所有成员函数,在 [=19= 中提供定义],并显式实例化您想要的 类 的有限列表。

Parent.h

template<typename T>
class ParentClass : public GrandparentClass<T>
{
    ParentClass();
};

class ParentClass<int>;
class ParentClass<long int>; // or whatever

Parent.cpp

template <typename T>
ParentClass::ParentClass() : grandparentMember(5) {}