Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/143.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.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++_Templates_Multiple Inheritance_Variadic Templates - Fatal编程技术网

C++ C++;从多重继承的模板类调用虚拟方法

C++ C++;从多重继承的模板类调用虚拟方法,c++,templates,multiple-inheritance,variadic-templates,C++,Templates,Multiple Inheritance,Variadic Templates,我这里有很多代码,但恐怕这是我能表达问题的最小代码,所以请耐心听我说: #include <iostream> #define ASINSTANCE(x, type, y) \ type * y = dynamic_cast<type *>(&(x)); \ if (y) cla

我这里有很多代码,但恐怕这是我能表达问题的最小代码,所以请耐心听我说:

#include <iostream>

#define ASINSTANCE(x, type, y)                                                 \
    type * y = dynamic_cast<type *>(&(x));                                     \
    if (y)

class Fruit {
    virtual void a() = 0; // This is to surpress the "Fruit isn't polymorphic" we'd otherwise get.
};

class Apple : public Fruit {
    virtual void a() {

    }
};

class Orange : public Fruit {
    virtual void a() {

    }
};

class Banana : public Fruit {
    virtual void a() {

    }
};

template<typename FruitType>
class FruitEater {

protected:
    virtual void eat(const FruitType & t) = 0;

};

template<typename... FruitTypes>
class MultiFruitEater : public FruitEater<FruitTypes>... {

public:
    // Eat any fruit if it belongs to FruitTypes (returns false otherwise).
    bool dispatchEat(const Fruit & fruit);

private:
    template<typename First>
    bool dispatchEatByType(const Fruit & fruit);

    template<typename First, typename Second, typename... Rest>
    bool dispatchEatByType(const Fruit & fruit);

};

class MyEater : public MultiFruitEater<Apple, Orange, Banana> {

protected:
    virtual void eat(const Apple & t);
    virtual void eat(const Orange & t);
    virtual void eat(const Banana & t);
};

void MyEater::eat(const Apple & t) {
    std::cout << "Ate apple." << std::endl;
}
void MyEater::eat(const Orange & t) {
    std::cout << "Ate orange." << std::endl;
}
void MyEater::eat(const Banana & t) {
    std::cout << "Ate banana." << std::endl;
}

template<typename... FruitTypes>
bool MultiFruitEater<FruitTypes...>::dispatchEat(const Fruit & fruit) {
    return dispatchEatByType<FruitTypes...>(fruit);
}

template<typename... FruitTypes>
template<typename First>
bool MultiFruitEater<FruitTypes...>::dispatchEatByType(const Fruit & fruit) {
    ASINSTANCE(fruit, const First, pCastFruit) {
        eat(*pCastFruit);
        return true;
    }
    return false;
}

template<typename... FruitTypes>
template<typename First, typename Second, typename... Rest>
bool MultiFruitEater<FruitTypes...>::dispatchEatByType(const Fruit & fruit) {
    ASINSTANCE(fruit, const First, pCastFruit) {
        eat(*pCastFruit);
        return true;
    }
    return dispatchEatByType<Second, Rest...>(fruit);
}

int main() {
    MyEater eater;
    Banana b;
    eater.dispatchEat(b);
}
我得到以下错误:

  • 错误C2385:对“eat”的访问不明确
  • 错误C3861:“eat”:找不到标识符
我试着将线路替换为:

this->FruitEater<First>::eat(*pCastFruit);
this->foulteater::eat(*pCastFruit);
错误现在更改为:

  • 错误LNK2019:未解析的外部符号“受保护:虚拟” void _u这个名字叫做水果食者::eat(类苹果常数&) (吃)?$FruitEater@VApple@@@@MAEXABVApple@@@Z)在函数中引用 “private:bool\uu thiscall multifruiteter::dispatchEatByType(类水果常量&)” (??$dispatchEatByType@VApple@@沃兰格@@VBanana@@@@$MultiFruitEater@VApple@@VOrange@@@VBanana@@@AAE_NABVFruit@@@Z)

  • 错误LNK2019:未解析的外部符号“受保护:虚拟” void _uthiscall水果食者::eat(类香蕉常数&) (吃)?$FruitEater@VBanana@@@@MAEXABVBanana@@@Z)在中引用 函数“private:bool\uu thiscall multifruiteter::dispatchEatByType(类) 常数&) (??$dispatchEatByType@VBanana@@@?$MultiFruitEater@VApple@@VOrange@@@VBanana@@@AAE_NABVFruit@@@Z)

有什么想法吗?

解决方案: 所以我得到了你的回复:

使用您的定义帮助:(当您创建时,您现在发送的类型不是常量

#define ASINSTANCE(x, type, y, eater)                                   \
  const type * y = dynamic_cast<const type *>(&(x));                    \
  FruitEater<type>* eater = dynamic_cast<FruitEater< type >*>(this);    \
  if (y && eater)
解释:(没有我想要的那么精确)
我认为这样做(
this->fruoteater::eat(*pCastFruit);
)的问题在于,您强制编译器使用fruoteater::eat()方法,这是一个虚拟的空白…

如果您将对
eat()
的调用更改为:
fruoteater&fe=*this;fe.eat(*pCastFruit);
,会发生什么?(您需要更改代码以允许访问该方法。)我得到了有关发生这种情况的原因的澄清。请参阅。这起到了作用,但现在,正如jxh所说,我们正在访问eat(一种受保护的方法)在一个据称不同的对象上,所以我们被拒绝访问。通过让MultiFruitEater成为水果食者的朋友来解决。@saarraz1不是我所做的吗?我不明白你的意思这完美地解决了问题,它只引入了另一个小错误(你的解决方案没有问题,别担心(:)哈哈,谢谢,错误(正如我在第一条评论中所说的)我们不能访问eat方法,因为它受保护,我们通过一个指针访问它,而不是这个。我通过让Multifruiteter成为水果食者的朋友来解决这个问题。
#define ASINSTANCE(x, type, y, eater)                                   \
  const type * y = dynamic_cast<const type *>(&(x));                    \
  FruitEater<type>* eater = dynamic_cast<FruitEater< type >*>(this);    \
  if (y && eater)
template<typename FruitType>
class FruitEater {

 protected:
  template<typename... Fruit> friend class MultiFruitEater;
  virtual void eat(const FruitType & t) = 0;

};
  ASINSTANCE(fruit, First, pCastFruit, eater) {
    eater->eat(*pCastFruit);
    return true;
  }