我认为您正在查看类似的内容,但不太确定。如果它不符合您的需求,请告诉我,我会放弃它以支持有需求的人。输出表明虚拟feed()
操作正确地完成了它的业务。为该函数安排一个潜在的可变参数包将花费我一些时间来烹饪一段时间,我什至不确定这是否可能。
但这应该让你接近。
#include <iostream>
#include <algorithm>
#include <type_traits>
#include <vector>
// base. enforces inheritance by SFINAE
template<typename Base, typename T, template<typename, typename...> class V>
typename std::enable_if<std::is_base_of<Base, T>::value>::type
invoke(void (Base::*func)(), const class V<T*>& vec)
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
for (auto p : vec)
(p->*func)();
}
// chain.
template<typename Base, typename T, template<typename, typename...> class V, typename... Args>
typename std::enable_if<std::is_base_of<Base, T>::value>::type
invoke(void (Base::*func)(), const class V<T*>& vec, Args... args)
{
invoke(func, vec);
invoke(func, args...);
}
int main()
{
struct Animal
{
virtual void feed()
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
} ;
struct Dog : public Animal
{
void feed()
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
} ;
struct StripedDog : public Dog {};
struct Cat : public Animal {};
struct SpottedCat : public Cat {};
std::vector<Dog*> doggies ;
std::vector<StripedDog*> stripedDoggies ;
std::vector<Cat*> catties ;
std::vector<SpottedCat*> spottedCatties ;
Dog dog;
doggies.push_back(&dog);
StripedDog sdog;
stripedDoggies.push_back(&sdog);
Cat cat;
catties.push_back(&cat);
invoke(&Animal::feed, doggies, stripedDoggies, catties, spottedCatties);
return 0;
}
输出
typename std::enable_if<std::is_base_of<Base, T>::value>::type invoke(void (Base::*)(), const class V<T *> &) [Base = Animal, T = Dog, V = vector]
virtual void main()::Dog::feed()
typename std::enable_if<std::is_base_of<Base, T>::value>::type invoke(void (Base::*)(), const class V<T *> &) [Base = Animal, T = StripedDog, V = vector]
virtual void main()::Dog::feed()
typename std::enable_if<std::is_base_of<Base, T>::value>::type invoke(void (Base::*)(), const class V<T *> &) [Base = Animal, T = Cat, V = vector]
virtual void main()::Animal::feed()
typename std::enable_if<std::is_base_of<Base, T>::value>::type invoke(void (Base::*)(), const class V<T *> &) [Base = Animal, T = SpottedCat, V = vector]
很抱歉不得不向右滚动才能看到漂亮打印中的类型,但它们很能说明问题,应该看看它是如何工作的。请注意,Dog
和StripedDog
容器都正确触发Dog::feed()
成员,而Cat
容器正确触发Animal::feed()
基础成员,因为它没有提供覆盖。
祝你好运,我希望它有所帮助。