C++11模板:如何确保类型继承自一个类?

3
在Java泛型中,当我想要确保某个泛型类的类型必须继承自一个类时,我可以按照以下方式编码:
public class MyHandler<T extends Serializable> {}

这意味着T必须扩展/实现类/接口Serializable,否则编译器将生成错误。
如何在C++11中实现相同的功能?我的意思是,如果我按照以下方式编写C++11代码:
template<typename T>
class MyHandler {}

在这段代码中,T 可以是任何类。但是,如果我想告诉类的使用者 T 必须继承类 boost::archive::text_oarchive (就像在 Java 中的 <T extends Serializable>),我该怎么办?

你想在编译时或运行时防止实例化你的类吗? - asmmo
通常这样做的目的是为了防止由于不兼容的类型参数导致失败的实例化产生难以理解的错误。因此,既然模板本来就是编译时的东西,在运行时防止它没有任何意义——你不能在运行时实例化一个模板。 - cdhowie
@cdhowie 我知道,但我更喜欢使用std::enable_if来解决这个问题,所以我才提出了那个问题。或者是我漏掉了什么吗? - asmmo
@asmmo std::enable_if和发布的答案中的技术都是100%编译时的。 - cdhowie
1个回答

4

你可以使用std::is_base_of进行检查。

template<typename T>
class MyHandler {
    static_assert(std::is_base_of<boost::archive::text_oarchive, T>::value, "T must inherit boost::archive::text_oarchive");
};

自 C++20 开始,我们可以使用 约束,例如。
template<typename T> requires std::is_base_of_v<boost::archive::text_oarchive, T>
class MyHandler {};

使用 std::is_convertible 更有意义吗?is_base_of 可以很好地处理私有和受保护的继承,我猜这并不符合 OP 的需求(根据与 Java 的比较)。 - Stephen Newell
@Yves,static_assert有什么问题吗? - Ted Lyngmo
@TedLyngmo 好的,我以为它就像assert一样。 - Yves
1
@Yves 好的,static_assert 在制作模板时可以帮助更清晰地生成错误消息。 - Ted Lyngmo
1
@TedLyngmo 好的,那么对我来说static_assert是可以的。 - Yves
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接