[英]Using a data member of the derived class in a requires clause of the base CRTP class
[英]Using `this` as a pointer to derived class in a base class in CRTP
我正在尝试使用CRTP来注册某些类的所有实时(已创建但尚未销毁)实例。 这对我很有用:
template <typename T>
class Registrable {
public:
void _register(T* p) { instances_.insert(p); }
void _unregister(T* p) { instances_.erase(instances_.find(p)); }
static const std::set<T*> & instances() { return instances_; }
private:
static std::set<T*> instances_;
};
template <typename T>
std::set<T*> Registrable<T>::instances_;
class Class : private Registrable<Class> {
public:
using Registrable<Class>::instances;
Class() { _register(this); }
Class(const Class &) { _register(this); }
Class(Class &&) { _register(this); }
~Class() { _unregister(this); }
void function() { }
};
int main() {
Class c;
auto upc = std::make_unique<Class>(c);
std::vector<Class> vc(5);
for (auto i : Class::instances())
i->function();
}
编辑:
更好的是不关心在派生类中注册和取消注册实例。 根据@ Jean-BaptisteYunès和@Aconcagua的解决方案:
template <typename T>
class Registrable {
public:
static const std::set<T*> & instances() { return instances_; }
protected:
Registrable() { instances_.insert(static_cast<T*>(this)); }
Registrable(const Registrable &) : Registrable() { }
Registrable(Registrable &&) : Registrable() { }
~Registrable() { instances_.erase(instances_.find(static_cast<T*>(this))); }
private:
static std::set<T*> instances_;
};
...
class Class : public Registrable<Class> { ... }
但是, 我也不确定这种铸件是否安全 。 特别是,如果Class
还将通过多重继承从另一个类派生。
@ amc176的答案声称,我可以假设演员会成功,但我更愿意确定。 根据@Aconcagua的评论,我可以肯定,这不是答案。
static_cast
不进行运行时检查以确保static_cast
转换是完全安全的。 无论如何,如你所知,类型T
将是一个可Registrable<T>
的派生类,你可以假设演员表会成功。
实际上,在cppreference中提到了这种强制转换通常在应用CRTP时使用(在链接中称为static polymorphism
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.