如何为 dynamic_cast 指定“所有参数化类型”或“所有参数列表”?
How to specify “all parameterized types” or “all argument lists” for a dynamic_cast?
我正在尝试调用派生 class 上的方法。派生的 class 有模板参数,但我不知道它们是什么。如何为 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
class 中存在的方法。这就是我寻找“所有参数列表”(而不是专业化)的方式的原因。
如果有帮助,真实世界的代码会创建数字签名。除了一个需要随机值 k
之外,所有受支持的签名方案。基础 class 具有创建随机 k
的代码。确定性签名需要非随机 k
,我们正在尝试捕获它。 DoOp
正在尝试为确定性过程获取非随机 k
。
你不能为所欲为。
尝试不同的计划。
我的建议是另一种虚方法。如果可以完成,此方法将执行您想要的任务,否则将失败。如果有两种方法可以做到,而不是失败你做任何有效的方法。
我正在尝试调用派生 class 上的方法。派生的 class 有模板参数,但我不知道它们是什么。如何为 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
class 中存在的方法。这就是我寻找“所有参数列表”(而不是专业化)的方式的原因。
如果有帮助,真实世界的代码会创建数字签名。除了一个需要随机值 k
之外,所有受支持的签名方案。基础 class 具有创建随机 k
的代码。确定性签名需要非随机 k
,我们正在尝试捕获它。 DoOp
正在尝试为确定性过程获取非随机 k
。
你不能为所欲为。
尝试不同的计划。
我的建议是另一种虚方法。如果可以完成,此方法将执行您想要的任务,否则将失败。如果有两种方法可以做到,而不是失败你做任何有效的方法。