在Java中,你可以定义泛型类,它只接受你选择的扩展类的类型,例如:
public class ObservableList<T extends List> {
...
}
这是使用“extends”关键字完成的。
在c++中是否有与此关键字简单等价的东西?
在Java中,你可以定义泛型类,它只接受你选择的扩展类的类型,例如:
public class ObservableList<T extends List> {
...
}
这是使用“extends”关键字完成的。
在c++中是否有与此关键字简单等价的东西?
当前回答
只接受类型List派生的类型T的等效函数如下所示
template<typename T,
typename std::enable_if<std::is_base_of<List, T>::value>::type* = nullptr>
class ObservableList
{
// ...
};
其他回答
据我所知,这在c++中是不可能的。不过,我们计划在新的c++ 0x标准中添加一个称为“概念”的特性,它可以提供您正在寻找的功能。这篇关于c++概念的维基百科文章将更详细地解释它。
我知道这并不能立即解决您的问题,但有一些c++编译器已经开始从新标准中添加特性,因此可能会找到一个已经实现了概念特性的编译器。
在c++中是否有与此关键字简单等价的东西?
No.
根据你想要实现的目标,可能会有足够的(甚至更好的)替代品。
我已经看了一些STL代码(在linux上,我认为它是从SGI的实现派生出来的)。它有“概念断言”;例如,如果您需要一个能够理解*x和++x的类型,则概念断言将在一个什么都不做的函数(或类似的东西)中包含该代码。它确实需要一些开销,所以把它放在一个定义依赖于#ifdef debug的宏中可能是聪明的。
如果子类关系确实是你想知道的,你可以在构造函数中断言T instanceof list(除非它在c++中“拼写”不同)。这样,你就可以通过测试来避免编译器无法为你检查它。
只接受类型List派生的类型T的等效函数如下所示
template<typename T,
typename std::enable_if<std::is_base_of<List, T>::value>::type* = nullptr>
class ObservableList
{
// ...
};
最简单的解决办法是忽略这个问题,虽然还没有人提到过。如果我试图在一个期望容器类(如vector或list)的函数模板中使用int作为模板类型,那么我将得到一个编译错误。粗暴而简单,但它解决了问题。编译器将尝试使用您指定的类型,如果失败,则生成编译错误。
唯一的问题是,您得到的错误消息将很难阅读。然而,这是一种非常常见的方法。标准库中充满了函数或类模板,它们期望从模板类型中获得某些行为,而不做任何检查所使用的类型是否有效的工作。
如果您想要更好的错误消息(或者如果您想要捕捉不会产生编译器错误,但仍然没有意义的情况),您可以根据您想要的复杂程度,使用Boost的静态断言或Boost concept_check库。
使用最新的编译器,可以使用内置的static_assert。
没有用于此类类型检查的关键字,但你可以放入一些至少会以有序方式失败的代码:
(1)如果你想让一个函数模板只接受某个基类X的参数,将它赋给函数中的X引用。 (2)如果你想接受函数但不接受原语,反之亦然,或者你想用其他方式过滤类,在你的函数中调用一个(空的)模板帮助函数,它只为你想接受的类定义。
你也可以在一个类的成员函数中使用(1)和(2)对整个类强制进行这些类型检查。
你可以把它放到一些智能宏来减轻你的痛苦。:)