再帰テンプレートを使用して、C++ で非常に単純な単一継承スタック トレースを実装しようとしています。
#include <iostream>
using namespace std;
template <class C> struct MakeAlias : C{ typedef C Base; };
class StackTrace{
public:
static int var;
virtual ~StackTrace() {}
template <class T> void printStackTrace(T* c){
if(typeid(T)==typeid(StackTrace))return;
cout << typeid(T).name() << "." << endl;
class T::Base *V;
printStackTrace(V);
}
};
class A : public MakeAlias<StackTrace>{
};
class B : public MakeAlias<A>{
};
class C : public MakeAlias<B>{
public:
void hello(){
cout << "hello from ";
StackTrace::printStackTrace(this);
cout << endl;
}
};
int main(){
C c;
c.hello();
}
すべて問題ないはずですが、コンパイルしようとすると、g++ は
if(typeid(T)==typeid(StackTrace))return;を無視します。次のエラーを返します。
st.cpp: In member function `void StackTrace::printStackTrace(T*) [with T = StackTrace]':
st.cpp:13: instantiated from `void StackTrace::printStackTrace(T*) [with T = A]'
st.cpp:13: instantiated from `void StackTrace::printStackTrace(T*) [with T = B]'
st.cpp:13: instantiated from `void StackTrace::printStackTrace(T*) [with T = C]'
st.cpp:24: instantiated from here
st.cpp:12: error: no type named `Base' in `class StackTrace'
st.cpp:13: error: no type named `Base' in `class StackTrace'
C::Base::Base::Base::Base /StackTrace::Base/ クラスを呼び出そうとしますが、実行時に呼び出されることはありません。printStackTrace 宣言の直後にreturn文を入れても同じエラーと評価されます。スコープとメンバー関数が動的にチェックされないのはなぜですか? また、コンパイラがreturnを無視するのはなぜですか?