一种编译时方法来测试模板参数 T 是否定义了自己的(静态)方法,而不考虑 T 的基类定义的方法

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

我在代码中使用静态类版本 CRTP(奇怪的重复模板模式)。那就是:

// Base class template using CRTP
template <typename Derived>
class Base {
public:
    // Static function that can be overridden by the derived class
    static void initialize() {
        Derived::initialize();
    }
};

// Derived class inheriting from the CRTP base class
class Derived : public Base<Derived> {
public:
    // Static member function with the same name and signature as the base class
    static void initialize() {
    }
};

由于基类是模板类,它可能会收到一个未定义initialize()函数的模板参数,在这种情况下Derived::initialize()将递归调用基类版本的initialize(),从而导致调用堆栈溢出.

我的问题是如何能够在编译时检查基类中的模板参数是否定义了自己的initialize()成员函数,而不考虑基类中存在的initialize()。

我确实在这里发现了许多与检查函数是否由模板参数定义相关的问题,但是当我尝试使用这些(SFINAE)时,他们报告在模板参数中定义了initialize(),因为其基类模板参数所表示的类继承了一个成员函数initialize()。

我想要的是一种编译时机制来测试模板参数是否定义了自己的(静态)方法,而不考虑模板参数所代表的类继承的任何基类定义的方法。

仅供参考,我使用 C++ 17 或更早版本。

c++ templates template-meta-programming sfinae
1个回答
0
投票

如果不进行检查,如果

Derived
没有
initialize
,将会出现无限递归。困难在于,当
Derived
实例化时,
Base
尚未完成。我想这可以通过一定程度的间接来解决。然而,更简单的方法是依赖在实例化
static_assert
时触发的
initialize

template <typename Derived>
class Base {
public:
    // Static function that can be overridden by the derived class
    static void initialize() {
        Derived::initialize();
        static_assert(&Derived::initialize != &Base::initialize);
    }
};

class Derived : public Base<Derived> {};

int main() {
    Derived::initialize();
}

现场演示

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