2016-12-08 4 views
0

派生クラスのメソッドを呼び出そうとしています。派生クラスはテンプレートパラメータを持っていますが、私はそれらが何であるか分かりません。 dynamic_castの「すべてのパラメータ化された型」または「すべての引数リスト」を指定するにはどうすればよいですか?以下はdynamic_castに「すべてのパラメータ化された型」または「すべての引数リスト」を指定する方法は?

MCVEであるが、ここで問題の推力です:

// Contrived, but close approximation 
DerivedOne<X> one; 
// Another one 
DerivedTwo<X,Y> two; 
// Maybe another one somewhere... 
DerivedTwo<X,Z> three; 

// Here's the problem 
Base& base = dynamic_cast<Base&>(two); 
if (base.HasOp()) 
{ 
    // By the time we get back to its a "DerivedTwo", we don't know 
    // or care what the template parameters are. All we know is it has 
    // the DoOp() method and we want to call it. 
    DerivedTwo& derived = dynamic_cast<DerivedTwo&>(base); 
    derived.DoOp(); 
} 

MCVEは私が望むほど最小限ではありませんが、モデル化する必要があるいくつかの移動の作品があります。また、ABIを維持するという要件もあり、かなりの量の痛みに責任があると思われます。


プログラム例

// Base interface/contract 
struct Base { 
    virtual bool HasOp() const { 
     return false; 
    } 
}; 

// structs to use a template parameters for derived classes 
struct X {}; struct Y {}; struct Z {}; 

// First derived class with first requirement 
template <class One> 
struct DerivedOne : public Base { 
    // Does not have DoOp() 
}; 

// Second derived class with second requirement 
template <class One, class Two> 
struct DerivedTwo : public Base { 
    virtual bool HasOp() const { 
     return true; 
    } 
    virtual void DoOp() const { 
     // ... 
    } 
}; 

int main(int argc, char* argv[]) 
{ 
    // Contrived, but close approximation 
    DerivedTwo<X,Y> two; 
    // Maybe another one somewhere... 
    DerivedTwo<X,Z> three; 

    // Here's the problem 
    Base& base = dynamic_cast<Base&>(two); 
    if (base.HasOp()) 
    { 
     // By the time we get back to its a "DerivedTwo", we don't know 
     // or care what the template parameters are. All we know is it has 
     // the DoOp() method and we want to call it. 
     DerivedTwo& derived = dynamic_cast<DerivedTwo&>(base); 
     derived.DoOp(); 
    } 

    return 0; 
} 

コンパイル私は、問題の行を変更した場合

C:\test>cl.exe /TP test.cxx 
Microsoft (R) C/C++ Optimizing Compiler Version 17.00.61030 for x86 

test.cxx 
test.cxx(42) : error C2955: 'DerivedTwo' : use of class template requires template argument list 
     test.cxx(19) : see declaration of 'DerivedTwo' 
test.cxx(45) : error C2662: 'DerivedTwo<One,Two>::DoOp' : cannot convert 'this' pointer from 'DerivedTwo' to 'const DerivedTwo<One,Two> &' 
     Reason: cannot convert from 'DerivedTwo' to 'const DerivedTwo<One,Two>' 
     Conversion requires a second user-defined-conversion operator or constructor 

を結果:

DerivedTwo<>& derived = dynamic_cast<DerivedTwo<>&>(base); 

は、その後、それは結果:

test.cxx 
test.cxx(44) : error C2976: 'DerivedTwo' : too few template arguments 
     test.cxx(19) : see declaration of 'DerivedTwo' 
     test.cxx(19) : see declaration of 'DerivedTwo' 
test.cxx(45) : error C2662: 'DerivedTwo<One,Two>::DoOp' : cannot convert 'this' pointer from 'DerivedTwo' to 'const DerivedTwo<One,Two> &' 
     Reason: cannot convert from 'DerivedTwo' to 'const DerivedTwo<One,Two>' 
     Conversion requires a second user-defined-conversion operator or constructor 

そのコンパイラは専門に私を強制するのではなく、すべてのDerivedTwoクラスの存在だメソッドの呼び出しを許可されるかのように。その理由は、私が(専門分野ではなく)「すべての議論一覧」を言う方法を探している理由です。


実際のコードでは、デジタル署名が作成されます。 1つを除くすべてのサポートされている署名方式は、ランダム値kを必要とします。基本クラスには、ランダムkを作成するコードがあります。確定性のある署名には、ランダムでないものが必要ですk、これをキャプチャしようとしています。 DoOpは、確定的プロセスのために非ランダムkを取得しようとしています。

+0

テンプレートの特殊化のいくつかがメソッドを省略することができるので、どのテンプレートインスタンス化にもキャストすることはできないと思います...あなたができることは、 'Base'と' DerivedTwo'の間に中間抽象クラスを作成できます... –

+0

'DoOp'をベースに仮想として定義し、' HasOp'がそこにあると言っていない場合は呼び出さないでください。これを行う1つの方法は 'DoOp'をプライベートにして、それを呼び出す前に存在するかどうかをチェックするパブリック関数を追加することです。別の方法は、基本クラスに空の実装を提供することです。派生型がそれをオーバーライドしない場合に呼び出されます。 –

+0

@jww [例](http://melpon.org/wandbox/permlink/Cn5jDMxFPSuyUUk1) –

答えて

1

あなたがしたいことはできません。

別のプランをお試しください。

私の提案は別の仮想的な方法です。このメソッドは、実行可能な場合は必要なタスクを実行し、そうでない場合は失敗します。それを行うには2つの方法がある場合、失敗するのではなく、どのような方法でも動作します。

+0

ありがとうYakk。私はそのことが起こるのを恐れる。残念ながら(恥ずかしいことに?)、私たちはこの機能を約9ヶ月間カットしようとしています(最初のPRは2月でした)。私たちが何かを試してABIを維持するたびに、私たちは問題に遭遇します。 – jww

関連する問題