何时在 c++23 中使用 CRTP 代替显式对象参数?

问题描述 投票:0回答:1

问题的简短版本

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 让我们在声明非函数成员和静态成员函数时引用类型。 但是有什么情况下这实际上有用吗?

(第二个问题:我的理解正确吗?我错过了什么吗?)

c++ templates crtp c++23
1个回答
0
投票

来自 https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0847r7.html#propose-syntax

具有显式对象参数的成员函数不能是静态或虚拟的,并且它们不能具有 cv 或 ref 限定符。我们将在后续章节中讨论对静态和虚拟的限制。

所以CRTP仍然是

virtual
static
功能的唯一途径。

© www.soinside.com 2019 - 2024. All rights reserved.