我知道C ++中缺少反射和基本模板机制,因此下面的示例无法正常工作。但是也许会有黑客以另一种方式实现预定目的?
postgres=# select to_json(now() at time zone 'America/New_York') NYC,
postgres-# to_json(now() at time zone 'Asia/Bangkok') Bangkok;
nyc | bangkok
------------------------------+------------------------------
"2019-03-15T04:41:07.789954" | "2019-03-15T15:41:07.789954"
在示例中,template <typename OwnerClass>
struct Template
{
OwnerClass *owner;
};
struct Base
{
virtual void funct ()
{
Template <decltype(*this)> temp;
// ...
}
};
struct Derived : public Base
{
void whatever ()
{
// supposed to infer this class and use Template<Derived>
// any chance some macro or constexpr magic could help?
funct();
}
};
调用虚拟方法Derived::whatever()
,并希望其将其自己的类名(派生)传递给模板。编译器抱怨“ Base::funct()
”。 'owner' declared as a pointer to a reference of type 'Base &'
不仅不提供类型名,而且不提供引用,编译器还无法事先知道从 Derived 调用了funct,这将需要制作decltype(*this)
模板。
但是,如果funct()
是模板,则每个派生类在每次调用时都需要传递自己的名称,这是非常冗长和多余的。
是否有黑客可以解决此限制,并通过调用funct()来推断调用类的类型名称?也许funct()
或constexpr
可以帮助编译器推断正确的类型并减少派生类中的冗长性?
答案 0 :(得分:1)
当前无法完成。 Base
是Base
,实例化Template <decltype(*this)>
时没有其他内容。您正在尝试将静态类型系统用于继承层次结构,该继承层次结构在运行时之前是无法解析的。这种完全相同的机制是在构造对象时不调用对象的virtual
成员函数的原因。
在将来,此限制可能会更改。 Deducing this proposal展示了实现这一目标的第一步。
答案 1 :(得分:1)
您应该使用CRTP模式(奇怪的重复模板模式)进行继承。
定义基类:
struct CBase {
virtual ~CBase() {}
virtual void function() = 0;
};
定义一个准备好的CRTP类:
template<typename T>
struct CBaseCrtp : public CBase {
virtual ~CBaseCrtp() {}
void function() override {
using DerivedType = T;
//do stuff
}
};
从CRTP继承一个:
struct Derived : public CBaseCrtp<Derived> {
};
应该可以。知道Derived类型的唯一方法是将其赋予基数!