【发布时间】:2014-12-08 17:23:39
【问题描述】:
我这里有很多代码,但恐怕这是我可以用来表达问题的尽可能少的代码,所以请多多包涵:
#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);
}
问题出在这行:
eat(*pCastFruit);
我收到以下错误:
- 错误 C2385:“吃”的访问不明确
- 错误 C3861:“吃”:找不到标识符
我尝试将行替换为:
this->FruitEater<First>::eat(*pCastFruit);
错误现在更改为:
错误 LNK2019:无法解析的外部符号“受保护:虚拟 void __thiscall FruitEater::eat(class Apple const &)" (?eat@?$FruitEater@VApple@@@@MAEXABVApple@@@Z) 在函数中引用 “私有:bool __thiscall MultiFruitEater::dispatchEatByType(class Fruit const &)” (??$dispatchEatByType@VApple@@VOrange@@VBanana@@@?$MultiFruitEater@VApple@@VOrange@@VBanana@@@@AAE_NABVFruit@@@Z)
错误 LNK2019:无法解析的外部符号“受保护:虚拟 void __thiscall FruitEater::eat(class Banana const &)" (?eat@?$FruitEater@VBanana@@@@MAEXABVBanana@@@Z) 函数“私有:bool __thiscall MultiFruitEater::dispatchEatByType(水果类 常量 &)" (??$dispatchEatByType@VBanana@@@?$MultiFruitEater@VApple@@VOrange@@VBanana@@@@AAE_NABVFruit@@@Z)
有什么想法吗?
【问题讨论】:
-
如果您将对
eat()的调用更改为:FruitEater<First> &fe = *this; fe.eat(*pCastFruit);,会发生什么情况? (您需要更改代码以允许访问该方法。) -
我得到了关于为什么会发生这种情况的澄清。见this question。
标签: c++ templates multiple-inheritance variadic-templates