Reputation: 110
Consider such code:
struct A
{
A() = default;
virtual ~A() = default;
};
struct B : public A
{
B() = default;
virtual ~B() = default;
};
struct C : public A
{
C() = default;
virtual ~C() = default;
};
struct D : public A
{
D() = default;
virtual ~D() = default;
};
struct E : public A
{
E() = default;
virtual ~E() = default;
};
template <typename CLASS1, typename CLASS2>
bool AreObjectsEqual(std::vector<A*>& vec)
{
return std::all_of(vec.begin(), vec.end(),
[](const auto v) { return (dynamic_cast<CLASS1*>(v) != nullptr || dynamic_cast<CLASS2*>(v) != nullptr); });
}
int main()
{
std::vector<A*> vec = { new D{}, new C{} };
std::cout << AreObjectsEqual<D, C>(vec) << std::endl;
std::vector<A*> vec1 = { new D{}, new C{}, new E{} };
std::cout << AreObjectsEqual<E, C>(vec) << std::endl;
return 0;
}
Above code checks whether a vector of pointers contains objects that can be casted into some classes. But what I really would like to do is to check more that two templates. Something like:
template <typename... CLASSES>
bool AreObjectsEqual(std::vector<A*>& vec)
{
return std::all_of(vec.begin(), vec.end(),
[](const auto v)
{
bool false = true;
for(auto CLASS : CLASSES)
retValue ||= (dynamic_cast<CLASS*>(v) != nullptr);
return retValue;
});
}
std::cout << AreObjectsEqual<B, C, D, E>(vec) << std::endl;
Is it possible to achieve that? Every examples of code with parameter pack had also an argument with parameter pack, and I don't need that. I just need to know how to iterate over template... CLASSES
Upvotes: 0
Views: 196
Reputation: 15908
In C++17 and later, you can use a fold-expression.
template <typename... CLASSES>
bool AreObjectsEqual(std::vector<A*>& vec)
{
return std::all_of(vec.begin(), vec.end(),
[](const auto v)
{
return (... || (dynamic_cast<CLASSES*>(v) != nullptr));
});
}
In C++11 & 14, there's a somewhat obfuscated idiom.
template <typename... CLASSES>
bool AreObjectsEqual(std::vector<A*>& vec)
{
return std::all_of(vec.begin(), vec.end(),
[](const auto v)
{
bool retVal = false;
using expand = int[];
(void)expand{retVal = retVal || (dynamic_cast<CLASSES*>(v) != nullptr)...};
return retVal;
});
}
Upvotes: 1