为什么从基类到派生类的static_case转换可以在基类内部工作,但不能在基类外部工作
class Base
{
public:
template <typename T>
int getValue() const { return static_cast<const T&>(*this).getValue(); }
};
class Derived: public Base
{
public:
Derived(int v): value(v) { }
int getValue() const { return value; }
int value;
};
class Another
{
int getValue() const { return 5; }
};
template <typename T>
void out(const Base & base) {
cout << base.getValue<T>() << '\n';
}
int main() {
Derived d(5);
Base b;
out<Derived>(d); //understandable, d has derived part.
out<Derived>(b); //don't understand, b is only base.
out<Another>(b); //compile time error
//static_cast<Derived>(b); //compile time error
}
我阅读了有关CRTP的this文章,偶然发现了此代码:
template <typename T>
class Base
{
public:
void doSomething()
{
T& derived = static_cast<T&>(*this);
use derived...
}
};
class Derived : public Base<Derived>
{
...
};
而且我也不太清楚转换在这里是如何工作的。
仍然,在CRTP中,有些事情是不可能的,例如出于简单的原因,可以在Base类的内部将Derived类的嵌套类型声明用作完整类型:与成员变量和函数不同,它们不完整且不接受正向查找。如果需要这种使用,则必须在Base之前定义第三种类型,包含必需的声明。
static_cast
转换仅在此转换合法的情况下使用。在您的代码中,您正在创建类Base
的对象,并试图将其转换为类Derived
。幸运的是,Derived::getValue()
的实现不使用任何数据成员,而是从文字中返回一个值。无论如何,这是未定义的行为。如果是CRTP,则不会创建Base
类的实例:仅使用Derived
类的实例。