静态多态性的 CRTP 与名称隐藏
CRTP vs name hiding for static polymorphism
使用 Curiously recurring template pattern (CRTP) 与名称隐藏来实现静态多态性有何不同?
例如,这是一个使用 CRTP 和名称隐藏演示静态多态性的简单示例:
template <typename T>
struct BaseCRTP {
void foo() {
static_cast<T*>(this)->foo();
}
void bar() {
std::cout << "bar from Base" << std::endl;
}
};
struct DerivedCRTP : public BaseCRTP<DerivedCRTP> {
void foo() {
std::cout << "foo from Derived" << std::endl;
}
};
struct BaseNH {
void foo() {}
void bar() {
std::cout << "bar from Base" << std::endl;
}
};
struct DerivedNH : public BaseNH {
void foo() {
std::cout << "foo from Derived" << std::endl;
}
};
template <typename T>
void useCRTP(BaseCRTP<T>& b) {
b.foo();
b.bar();
}
template <typename T>
void useNH(T b) {
b.foo();
b.bar();
}
int main(int argc, char** argv) {
DerivedCRTP instance_crtp; // "foo from Derived"
DerivedNH instance_nm; // "bar from Base"
useCRTP(instance_crtp); // "foo from Derived"
useNH(instance_nm); // "bar from Base"
return 0;
}
澄清一下,这不是关于机制的问题,而是关于行为和使用的问题。
考虑基本 class 方法调用其他方法的情况。
使用 CRTP 可以覆盖调用的方法。
名称隐藏没有覆盖机制。
例子。
此代码将 CRTP 用于静态多态性,其中 kind
方法在派生的 class.
中被覆盖
#include <iostream>
using namespace std;
template< class Derived >
class Animal
{
public:
auto self() const
-> Derived const&
{ return static_cast<Derived const&>( *this ); }
auto kind() const -> char const* { return "Animal"; }
void identify() const { cout << "I'm a " << self().kind() << "." << endl; }
};
class Dog
: public Animal< Dog >
{
public:
auto kind() const -> char const* { return "Dog"; }
};
auto main() -> int
{
Dog().identify();
}
使用 Curiously recurring template pattern (CRTP) 与名称隐藏来实现静态多态性有何不同?
例如,这是一个使用 CRTP 和名称隐藏演示静态多态性的简单示例:
template <typename T>
struct BaseCRTP {
void foo() {
static_cast<T*>(this)->foo();
}
void bar() {
std::cout << "bar from Base" << std::endl;
}
};
struct DerivedCRTP : public BaseCRTP<DerivedCRTP> {
void foo() {
std::cout << "foo from Derived" << std::endl;
}
};
struct BaseNH {
void foo() {}
void bar() {
std::cout << "bar from Base" << std::endl;
}
};
struct DerivedNH : public BaseNH {
void foo() {
std::cout << "foo from Derived" << std::endl;
}
};
template <typename T>
void useCRTP(BaseCRTP<T>& b) {
b.foo();
b.bar();
}
template <typename T>
void useNH(T b) {
b.foo();
b.bar();
}
int main(int argc, char** argv) {
DerivedCRTP instance_crtp; // "foo from Derived"
DerivedNH instance_nm; // "bar from Base"
useCRTP(instance_crtp); // "foo from Derived"
useNH(instance_nm); // "bar from Base"
return 0;
}
澄清一下,这不是关于机制的问题,而是关于行为和使用的问题。
考虑基本 class 方法调用其他方法的情况。
使用 CRTP 可以覆盖调用的方法。
名称隐藏没有覆盖机制。
例子。
此代码将 CRTP 用于静态多态性,其中 kind
方法在派生的 class.
#include <iostream>
using namespace std;
template< class Derived >
class Animal
{
public:
auto self() const
-> Derived const&
{ return static_cast<Derived const&>( *this ); }
auto kind() const -> char const* { return "Animal"; }
void identify() const { cout << "I'm a " << self().kind() << "." << endl; }
};
class Dog
: public Animal< Dog >
{
public:
auto kind() const -> char const* { return "Dog"; }
};
auto main() -> int
{
Dog().identify();
}