提问人:jepugs 提问时间:10/27/2023 更新时间:10/28/2023 访问量:168
何时在 c++23 中对显式对象参数使用 CRTP?
When to use CRTP over explicit object parameter in c++23?
问:
问题的简短版本
C++23 为我们提供了一种编写 mixin 类的新方法(而不是 CRTP)。在哪些情况下,CRTP 仍是首选?
两种方法的总结
CRTP 是 C++ 中一个强大的习惯用语,它利用模板在运行时自动生成特定于类型的行为。这通常用于创建 mixin 类。
C++23 引入了显式对象参数,允许在非静态成员函数的参数列表中显式引用类名。因此,模板非静态成员函数可以访问派生类,无需将 mixin 专门化于派生类。
下面是一个示例,说明了新旧方法。
// classic CRTP (old approach)
template <typename T>
class MyMixin<T> {
// ...
void foo() {
// Stuff using T...
}
};
// have to specialize MyMixin over MyType
class MyType : public MyMixin<MyType> {
// ...
};
// explicit object parameter (C++23 approach)
class MyMixin {
// ...
template <typename T>
void foo(this T* self) {
// Stuff using T...
}
};
// better syntax for mixins
class MyType : public MyMixin {
// ...
};
显然,新方法在派生类中带来了更简洁的语法。例如,它可以让我们避免像这样粗糙的事情:
template<typename x, typename y, typename z, typename w>
class MyWackyContainer : public MyMixin<MyWackyContainer<x,y,z,w>>
因为我们不必为新方法提供模板参数。MyMixin
完整问题
根据本文的摘要(解决了前面提到的问题),
虽然 [添加显式对象参数] 在许多地方已经消除了使用 CRTP 的需要,但仍然存在必须使用此模式表示的情况。
我能想到的 CRTP 和新方法之间的唯一功能区别是,CRTP 允许我们在声明非函数成员和静态成员函数时引用该类型。但是,有没有一种情况是这实际上是有用的呢?
(次要问题:我的理解正确吗?我错过了什么吗?
答:
低至 https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0847r7.html#proposed-syntax
具有显式对象参数的成员函数不能是静态的或虚拟的,并且不能具有 cv 或 ref 限定符。
因此,CRTP仍然是唯一的方式和功能。virtual
static
最大的区别在于 CRTP 基类是不同的类型,在显式对象参数版本中没有等效的类型。这些类型可能很有用。
静态成员就是一个例子。由于具有不同的类型,因此可以实现仅在单个派生类中共享的静态成员,而不是在所有派生类之间共享的静态成员。
但是,您可能只需要这些类型来做任何事情,例如,作为放置类型别名定义的地方。
评论