我正在尝试在派生类上调用方法。派生类有模板参数,但我不知道它们是什么。如何为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
类中存在的方法。这就是我寻找说“所有参数列表”(而不是专业化)的方式的原因。
如果有帮助,真实世界代码会创建数字签名。除了一个需要随机值k
之外,所有支持的签名方案。基类具有创建随机k
的代码。确定性签名需要非随机k
,我们正试图捕获它。 DoOp
正试图获得确定性过程的非随机k
。
答案 0 :(得分:1)
你无法做你想做的事。
尝试不同的计划。
我的建议是另一种虚拟方法。如果可以完成,则此方法执行您想要的任务,否则将失败。如果有两种方法可以做到,而不是失败,你做任何有效的方法。