C++ 如何在参数中使用不匹配的引用修饰符动态转换可变模板?
我有一个类层次结构,其中基类包含一个函数,该函数测试C++ 如何在参数中使用不匹配的引用修饰符动态转换可变模板?,c++,c++11,variadic-templates,dynamic-cast,perfect-forwarding,C++,C++11,Variadic Templates,Dynamic Cast,Perfect Forwarding,我有一个类层次结构,其中基类包含一个函数,该函数测试动态\u cast该指针是否根据它接收的参数转换为派生模板类型 问题是dynamic\u cast操作符检查参数的精确匹配,并考虑它们是否为ref。我需要下面的例子来处理这两种情况,有办法吗 template <typename... P> struct Derived; struct Base { virtual ~Base() {} template <typename... P> voi
动态\u cast
该指针是否根据它接收的参数转换为派生模板类型
问题是dynamic\u cast
操作符检查参数的精确匹配,并考虑它们是否为ref。我需要下面的例子来处理这两种情况,有办法吗
template <typename... P>
struct Derived;
struct Base
{
virtual ~Base() {}
template <typename... P>
void doCast(P&&... p) {
Derived<P...> *res=dynamic_cast<Derived<P...> *>(this);
if (!res)
std::cout<<"Failed."<<std::endl;
else {
std::cout<<"Success."<<std::endl;
res->doSomethingWithP(std::forward<P>(p)...);
}
}
};
template <typename... P>
struct Derived: public Base
{
void doSomethingWithP(P... p) {
/*Whatever, doesn't matter*/
}
};
int main(int argc, char **argv)
{
Derived<int, int, int> derived;
Base *b=&derived;
int x=10;
int y=20;
int z=30;
//The two calls must succeed.
b->doCast(x,y,z); //Failed.
b->doCast(10,20,30); //Success.
return 0;
}
模板
结构派生;
结构基
{
虚拟~Base(){}
模板
作废文件(P&&…P){
派生*res=动态_cast(此);
如果(!res)
std::cout只是将我的注释移动到一个答案。在典型情况下,如果派生的
和派生的
都被允许作为类型,Base::doCast
将必须对每个参数类型执行两个不同的强制转换,或者2^N
总强制转换。这是不可行的
但是,您可以做的是:(1)要求派生的
的模板参数不是引用,(2)让它通过引用获取其参数。因此,我们只需删除所有p
上的引用:
template <typename... P>
void doCast(P&&... p) {
if (auto res = dynamic_cast<Derived<std::remove_reference_t<P>...>*>(this)) {
std::cout << "Success." << std::endl;
res->doSomethingWithP(p...); // NOT forward
}
else {
std::cout << "Failed." << std::endl;
}
}
模板
作废文件(P&&…P){
如果(自动恢复=动态施法(本)){
std::cout To clear-你真的会实例化派生的
?在这种情况下b->doCast(10,20);
应该做什么?或者说,你真的应该b->doCast(x)做什么
如果派生的
和派生的
都是可能的,怎么办?好的,这样它们就可以作为常量的引用。同样的问题是,派生的
或派生的
?如果这个类是int
或常量int&
,那么这两个铸件都应该很好。@LoPiTaL你不理解这个问题。比如说doCast
使用5个参数调用,这些参数的类型分别为A
,B
,…,E
。这意味着我们必须潜在地检查{A
,A常量&
}x{B
,B常量&
}x{C
,C常量&
x…这是32个潜在的Derived
类型!它工作起来很有魅力!非常感谢!只是一个旁注,因为我没有使用c++14,我不能使用类型std::remove\u reference\t
,所以为了得到正确的类型名,定义应该如下:Derived*
template <typename... P>
struct Derived: public Base
{
void doSomethingWithP(P&... ) {
/*Whatever, doesn't matter*/
}
};
template<bool...> struct bool_pack;
template<bool f, bool... bs>
using all_same = std::is_same<bool_pack<bs..., f>, bool_pack<f, bs...>>;
template <bool... bs>
using none = all_same<false, bs...>;
template <typename... P>
struct Derived: public Base
{
static_assert(none<std::is_reference<P>::value...>::value,
"Can't make Derived with references");
...
};