带有继承列表的 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) {}
是否可以在 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) {}