奇怪的循环模板和模板参数依赖子类化问题 [英] Curiously Recurring Template and Template parameter dependent subclassing issues
问题描述
我想让以下代码工作
template < class __derived, class __object = typename __derived::Object >
struct Base {
using Derived = __derived;
using Object = __object;
void function(Object o) { return Derived::function(s); }
}
//template < class __derived >
//struct Base {
// using Derived = __derived;
// using Object = typename Derived::Object;
// void function(Object o) { return Derived::function(s); }
//}
template < class __object >
struct Derived : public Base< Derived< __Object > > {
using Object = __object;
void function(Object o) { ... }
}
我通过声明
Derived<double> obj;
Problem is, the compiler claims not to be able to find the symbol Object
inside the Derived
class while deducing the second template parameter for the Base
class. The same error is also generated by the commented version.
我试图在Eigen3代码的灵感下,特别是CRTP(奇怪的循环模板模式)以避免使用虚拟函数。 Eigen3实际上使用一个 traits
类,但我不知道如何模仿这种情况。
任何人有任何建议吗?提前感谢!
I am trying to do this under inspiration of Eigen3 code, particularly the CRTP (Curiously Recurring Template Pattern) they use in order to avoid use of virtual functions. Eigen3 actually uses a traits
class but I can't figure out how to imitate that for the present case.
Anyone has any suggestion about this? Thanks in advance!
推荐答案
通常,如果你希望A继承B,那么B不能知道A的任何东西,声明:
Normally, if you want A to inherit from B, then B cannot know anything about A other than it's declaration:
template < class __object >
struct Derived;
不幸的是,你想获得更多,所以你必须使用类型trait: p>
Unfortunately, you want to get more, so you'll have to use a type trait:
template<class __derived>
struct Base_traits {
//using Object = ?????;
};
template<class __object>
struct Base_traits<Derived<__object>> {
using Object = __object; //note, this also can't inspect B.
};
Base
c $ c> Base_traits 所有它想要的,因为traits不检查 B
。
The Base
class can inspect the Base_traits
all it wants, because the traits don't inspect B
at all.
template < class __derived, class __object = typename Base_traits<__derived>::Object >
struct Base {
using Derived = __derived;
using Object = typename Base_traits<__derived>::Object;
//or
using Object = __object;
不相关的前导双下划线不允许由凡人使用,请使用单个前导下划线后跟小写字母。
Unrelated, leading double underscores are disallowed for use by mortals, use a single leading underscore followed by a lowercase letter. Alternatively, use a trailing underscore.
此外,语法
void function(Object o) { return Derived::function(s); }
无法工作,因为这种符号不能用于upcasts,只能用于downcasts。 Ergo,你必须在这
上使用 static_cast
。因为那是丑陋的,我把它放在一个函数后面:
Won't work, because that notation cannot be used for upcasts, only downcasts. Ergo, you have to use static_cast
on the this
. Since that's vaguely ugly, I put it behind a function:
void foo(Object o) { self()->bar(o); }
private:
__derived* self() {return static_cast<__derived*>(this);}
const __derived* self() const {return static_cast<__derived*>(this);}
};
完整代码: http://coliru.stacked-crooked.com/a/81595b0fcd36ab93
这篇关于奇怪的循环模板和模板参数依赖子类化问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!