使用具有相同成员函数名称的CRTP

时间:2017-10-17 21:56:31

标签: c++ inheritance crtp

当我看到使用的CRTP模式时,似乎在基类型中调用的函数名称始终指向派生类型中不同名称的实现函数(例如:foo()在base中进行调用{ {1}}。

有没有办法使用相同的函数名实现CRTP模式?我有一个更长的继承链,其中函数可能没有在链的第一级具体实现,因此必须使用不同的函数名称不是非常干净/可读。

我希望得到以下内容:

static_cast<DerivedType*>(this)->foo_implementation();

当然编译器并没有抱怨这一点,但我认为它会导致隐式vtable查找(尽管template <typename SecondType> struct FirstType { void foo() { static_cast<SecondType*>(this)->foo(); } }; template <typename ThirdType> struct SecondType : FirstType<SecondType> { void foo() { static_cast<ThirdType*>(this)->foo(); } }; struct ThirdType : SecondType<ThirdType> { void foo() { // Concrete implementation here } }; 关键字没有出现),从而破坏了使用CRTP的目的。

2 个答案:

答案 0 :(得分:1)

你可以很好地为两个函数使用相同的名称,它可以正常工作。

使用不同名称的优点是无法在派生类中实现该函数将导致编译器错误,而不是无限递归和运行时可能的堆栈溢出。

答案 1 :(得分:0)

为什么不断言成员函数不同呢?从 ThirdType 中删除 foo() 会给你一个编译错误和一条很好的消息。

#include <type_traits>

template <typename SecondType>
struct FirstType {

    void foo() {
        static_assert(
            !std::is_same<
                decltype(&FirstType::foo),
                decltype(&SecondType::foo)
             >::value,
            "SecondType must implement method 'void foo()'");
        static_cast<SecondType*>(this)->foo();
    }

};

template <typename ThirdType>
struct SecondType : FirstType<SecondType<ThirdType>> {

    void foo() {
        static_assert(
            !std::is_same<
                decltype(&SecondType::foo),
                decltype(&ThirdType::foo)
             >::value,
            "ThirdType must implement method 'void foo()'");
        static_cast<ThirdType*>(this)->foo();
    }

};

struct ThirdType : SecondType<ThirdType> {

    void foo() {
        // Concrete implementation here
    }

};

template class SecondType<ThirdType>;
template class FirstType<SecondType<ThirdType>>;