次のコード(より大きいプログラムから圧縮されている)は、clangまたはgccでコンパイルされません。メソッドポインタをテンプレートパラメータとして渡します:ここで継承されたメソッドを使用できないのはなぜですか?
bad.cc:15:3: error: no matching function for call to 'f1'
f1<S2, &S2::m1>(this);
^~~~~~~~~~~~~~~
bad.cc:21:5: note: in instantiation of member function 'S2<S1>::m3' requested
here
o.m3();
^
bad.cc:10:43: note: candidate template ignored: invalid explicitly-specified
argument for template parameter 'm'
template<typename S, void (S::*m)()> void f1(S* o) {
^
1 error generated.
私はm2
でm1
を交換するときに、このコードはコンパイルされます。
struct S1 {
void m1() {}
};
template<typename B> struct S2 : B {
void m2() {}
void m3();
};
template<typename S, void (S::*m)()> void f1(S* o) {
(o->*m)();
}
template<typename B> void S2<B>::m3() {
f1<S2, &S2::m1>(this);
}
int main() {
void (S2<S1>::*m)() = &S2<S1>::m1;
S2<S1> o;
o.m3();
}
はここで打ち鳴らすのエラーメッセージです。明らかにコンパイラはm1
(m1
をm4
に置き換えたときに別のメッセージを知っている)ので、なぜこのコンテキストではポインタが無効であるべきですか?
「f1(this);」と言ってみませんか? –
@Kerrek SB 'S1'は' B'の唯一の可能性ではないので。 – notagain
'S2'ではなく' B'で動作しますが、これは知っておくと便利ですが、 'm1'が基本クラスで定義されていると仮定する必要がない場合はいいでしょう。 – notagain