CRTP为什么是成员查找运行时?

时间:2017-07-20 23:27:09

标签: c++11 crtp

或者至少我认为是。 请考虑以下代码

#include <iostream>
#include <memory>

struct BaseBase {
    virtual void foo() = 0;
    virtual ~BaseBase(){}
};

template <typename Derived>
struct Base : BaseBase{
    void foo() override{
        static_cast<Derived*>(this)->foo();
    }
};

struct D1 : Base<D1> {};
struct Unrelated {};

// no runtime polymorphism
template <typename SDerived>
struct SBase{
    void foo() {
        static_cast<SDerived*>(this)->foo();
    }
};

struct SD1 : SBase<SD1> {};


template <typename T, typename ...Args>
void doFoo(Args&&... args){
    T* t = new T(std::forward<Args>(args)...);
    t->foo();
}

int main(){
    doFoo<Unrelated>(); //compile time error, foo not found in unrelated
    doFoo<SD1>(); //runtime crash
    doFoo<D1>(); //runtime crash
    return 0;
}

我希望编译器能够在foo的编译时检查doFoo是否存在,但在两种情况下,基数为virtual且没有{{在基础中,代码编译得很好但在运行时崩溃。

为什么会这样?

编辑:clang setup

virtual

clang version 4.0.1 (tags/RELEASE_401/final) Target: x86_64-unknown-linux-gnu 注释掉编译。

和g ++设置

doFoo<Unrelated>()

编译gcc version 7.1.1 20170630 (GCC) 注释掉。

1 个答案:

答案 0 :(得分:3)

这是因为这两个类都有一个名为foo的函数。它存在于每个类的基类中。

但是,所有函数都会调用自身,这最终会导致堆栈溢出。