Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在参数中使用不匹配的引用修饰符动态转换可变模板?_C++_C++11_Variadic Templates_Dynamic Cast_Perfect Forwarding - Fatal编程技术网

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");
    ...
};