CRTP:具有基于派生参数的函数
CRTP: function with derived-based argument
这是我正在尝试执行的操作的最小版本:
template<typename D>
struct Base {
void common() {
// ... do something ...
static_cast<D *>(this)->impl();
// ... do something ...
}
void common_with_arg(typename D::Arg arg) {
// ... do something ...
static_cast<D *>(this)->impl_with_arg(arg);
// ... do something more ...
}
};
struct Derived : Base<Derived> {
void impl() { }
using Arg = int;
void impl_with_arg(Arg arg) { }
};
Base::common()
和 Derived::impl()
工作正常(如预期)。
Base::common_with_arg()
和 Derived::impl_with_arg()
,但是,不要。
例如,使用 gcc,我得到以下错误:
1.cc: In instantiation of ‘struct Base<Derived>’:
1.cc:18:18: required from here
1.cc:11:7: error: invalid use of incomplete type ‘struct Derived’
void common_with_arg(typename D::Arg arg) {
^~~~~~~~~~~~~~~
1.cc:18:8: note: forward declaration of ‘struct Derived’
struct Derived : Base<Derived> {
凭直觉(不了解有关模板实例化的所有细节),这似乎是一个明智的错误。是否有其他方法可以实现相同的功能?
void common_with_arg(typename D::Arg arg)
// ^^^^^^
您无法在此处访问 D::Arg
,因为需要 Derived
的定义。但是该定义永远不可用,因为 Base
模板正在此处实例化...
struct Derived : Base<Derived> {
// ^^^^^^^^^^^^^
...其中 Derived
尚未完全定义。
一种可能的解决方法是将 common_with_arg
设为函数模板:
template <typename T>
void common_with_arg(T&& arg) {
// ... do something ...
static_cast<D *>(this)->impl_with_arg(std::forward<T>(arg));
// ... do something more ...
}
如果你真的需要 Arg
类型别名,请阅读这个问题:
"C++ static polymorphism (CRTP) and using typedefs from derived classes".
这是我正在尝试执行的操作的最小版本:
template<typename D>
struct Base {
void common() {
// ... do something ...
static_cast<D *>(this)->impl();
// ... do something ...
}
void common_with_arg(typename D::Arg arg) {
// ... do something ...
static_cast<D *>(this)->impl_with_arg(arg);
// ... do something more ...
}
};
struct Derived : Base<Derived> {
void impl() { }
using Arg = int;
void impl_with_arg(Arg arg) { }
};
Base::common()
和 Derived::impl()
工作正常(如预期)。
Base::common_with_arg()
和 Derived::impl_with_arg()
,但是,不要。
例如,使用 gcc,我得到以下错误:
1.cc: In instantiation of ‘struct Base<Derived>’:
1.cc:18:18: required from here
1.cc:11:7: error: invalid use of incomplete type ‘struct Derived’
void common_with_arg(typename D::Arg arg) {
^~~~~~~~~~~~~~~
1.cc:18:8: note: forward declaration of ‘struct Derived’
struct Derived : Base<Derived> {
凭直觉(不了解有关模板实例化的所有细节),这似乎是一个明智的错误。是否有其他方法可以实现相同的功能?
void common_with_arg(typename D::Arg arg)
// ^^^^^^
您无法在此处访问 D::Arg
,因为需要 Derived
的定义。但是该定义永远不可用,因为 Base
模板正在此处实例化...
struct Derived : Base<Derived> {
// ^^^^^^^^^^^^^
...其中 Derived
尚未完全定义。
一种可能的解决方法是将 common_with_arg
设为函数模板:
template <typename T>
void common_with_arg(T&& arg) {
// ... do something ...
static_cast<D *>(this)->impl_with_arg(std::forward<T>(arg));
// ... do something more ...
}
如果你真的需要 Arg
类型别名,请阅读这个问题:
"C++ static polymorphism (CRTP) and using typedefs from derived classes".