c++元编程:必须继承抽象类的模板参数
C++ meta-programming: A template parameter which *must* inherit an abstract class
我有一个用于比较+哈希值的抽象类:
class Key
{
public:
virtual bool operator ==(const Key&) const = 0;
virtual bool operator !=(const Key&) const = 0;
virtual u32 hashcode() const = 0;
};
和继承它的具体类C
class C : public Key
{
private:
u32 a, b;
public:
static const C& null; // a prototype for representing a "no value" C
// Some reasonable implementation; it's just a pair
// ...
};
和我想实现一个模板化HashSet类:
template<class T inherits Key, const T& proto> class HashSet
{
//...
};
T是存储在这些集合中的值的类型。prototype应该是T的一个实例,用于集合包含的目的,作为类型T的"空"值。我对c++有相当的经验,但对TMP不是特别有经验,尽管它看起来应该是令人尴尬的简单实现,但我似乎无法弄清楚像我的伪代码"类T继承密钥"这样的东西实际上是如何在c++中完成的。我希望能够创建C实例的哈希集,如:
HashSet<C, C::null> myset;
谁能告诉我在c++中处理这种情况的合适和习惯的方法是什么?谢谢你!
您可以使用std::enable_if_t
和std::is_base_of
:
template<class T, const T& proto,
std::enable_if_t<std::is_base_of<Key,T>::value>* = nullptr>
class HashSet
{
//...
};
现在HashSet
实例化只有在T
继承Key
时才有效。
std::enable_if_t
是c++ 14的一个特性。如果你坚持使用c++ 11,你可以使用typename std::enable_if<...>::type
。
现场演示
另一个选项是使用static_assert
:
template<class T, const T& proto>
class HashSet
{
static_assert(std::is_base_of<Key, T>::value, "T must inherit from Key");
};
这可能更清楚一些,给你一个更友好的错误消息,但是你的类型约束不再在类声明中给出。
使用概念,我们将获得更清晰、更好的错误消息,并在声明中保留约束:
template <class Base, class Derived>
concept bool IsBaseOf = std::is_base_of<Base, Derived>::value;
template<class T, const T& proto>
requires IsBaseOf<Key,T>
class HashSet
{};
谁能告诉我在c++中处理这种情况的合适和习惯的方法是什么?
那将简单地不处理它。如果用户传入一个从Key
派生的类型,那么即使您没有在代码注释中将其作为显式要求添加,模板实例化也会工作。如果用户传入一个无效的模板参数,那么事情将会中断。
下一个版本的c++可能会支持清楚地包括这样的注释,但在当前的c++版本中,虽然有一些技巧可以使用,但除了在有限的情况下,惯用的方法是不要麻烦它。
相关文章:
- 无法创建抽象类的实例
- 用pybind11包装C++抽象类时出错
- 如何处理从一个对象传递到另一个在C++中具有公共抽象类的对象的消息
- 有没有办法按值将纯抽象类的所有子类传递给 C++ 中的函数?
- 如何将子类作为函数的参数传递给期望基类,然后将该对象传递到指向这些抽象类对象的指针向量中?
- 无法实例化抽象类,但类不是抽象/派生方法的参数
- 为什么不能将std :: async用于接收对抽象类作为参数的函数
- 使用“std::function”(如语法)时,使用抽象类作为模板参数
- C++ 抽象类采用派生类参数
- 将抽象类作为参数传递给C++ Cython
- 不带模板参数的抽象类的实现
- C++抽象类参数错误解决方法
- 通过抽象类将参数传递给祖父母类的构造函数
- 在派生类中为抽象类函数传递附加参数
- c++元编程:必须继承抽象类的模板参数
- 编译错误:在类构造函数中将抽象类作为参数传递
- 抽象类作为参数(接口用例)
- c++中使用抽象类作为函数的参数
- 无法实例化抽象类:为什么模板参数(引用)导致这种情况
- 如何以抽象类作为参数继承和实现纯虚方法