2017-02-14 7 views
0

オブジェクト型の種類に応じて異なる種類のファンクタの呼び出しを呼び出すプログラムでパターンを使用しています。以下のコードでは、b1オブジェクトは、派生ファンクタタイプFunctorXで明示的にインスタンス化されています。しかし、コード内で呼び出しを行うと、派生ファンクタの代わりに基本ファンクタが呼び出されます。何故ですか?派生ファンクタがテンプレートパラメータとして渡されたときに呼び出されない

struct Functor 
{ 
    Functor() {} 
    ~Functor() {} 

    virtual int operator()() { return 33; } 
}; 

struct FunctorX : public Functor 
{ 
    FunctorX() : Functor() {} 
    ~FunctorX() {} 

    int operator()() { return 44; } 
}; 

template< typename FunctorT > 
struct B 
{ 
    B(FunctorT FunctorArg) : Functor { FunctorArg } {} 
    ~B() {} 

    FunctorT Functor; 
}; 

int main() 
{ 
    B<Functor> b1 { FunctorX() }; // initialize with derived functor. Derived functor gets instantiated. 
    int num = b1.Functor(); // error: calls base functor, not derived functor 

    return 0; 
} 
+0

@ BarryはBのメンバファンクタをptrに変更すると、B < Functor > b1 {new FunctorX()}; 'を実行してスライスを修正します。しかし、それでは、「b1」の呼び出しはどうなるでしょうか? 'エラーC2064:' b1.Functor(); 'を呼び出すと、termは0引数を取る関数に評価されません。 – rtischer8277

+0

@Barry私はそれを持っています: 'int num =(* b1.Functor)();' – rtischer8277

答えて

0

B<Functor>はタイプFunctorのオブジェクトを保持しています。そのオブジェクトをタイプFunctorXのオブジェクトで初期化できますが、保存するとオブジェクトはスライスされてFunctorと入力されます。 unsigned int i = std::numeric_limits<unsigned long long>::max()と同じように、格納された値の型はunsigned intですが、型がunsigned long longの値で初期化されています。

+0

これはスライスの例ではありません。 – Barry

+0

@Barry - これはまさにその例です: "型が' unsigned long long'の値で初期化されていても、格納された値は 'int'型です。そして、それはスライシングの基本的な問題です。 –

+0

狭いコンバージョンとスライスは異なるものです。 – Barry

関連する問題