Here's how to implement it using templates:
#include <iostream> #include <iomanip> template<class T0> bool AreEqual(T0 t0) { return true; } template<class T0, class T1, class... Args> bool AreEqual(T0 t0, T1 t1, Args ... args) { return t0 == t1 && AreEqual(t1, args...); } int main () { std::cout << std::boolalpha; // All of the following calls return true: std::cout<< AreEqual(1, 1) << "\n"; std::cout<< AreEqual(1, 1, 1) << "\n"; std::cout<< AreEqual(1, 1, 1, 1) << "\n"; std::cout<< AreEqual(1, 1, 1, 1, 1) << "\n\n"; // All of the following calls return false: std::cout<< AreEqual(1, 2) << "\n"; std::cout<< AreEqual(1, 2, 1) << "\n"; std::cout<< AreEqual(1, 7, 3, 1) << "\n"; std::cout<< AreEqual(1, 4, 1, 1, 1) << "\n"; }
You should consider whether these options are suitable for your use:
- Use links instead of passing by value
- Make an invariant template with two parameters instead of one.
In addition, a non-recursive version is provided here. Unfortunately, this is not a short circuit. To see a non-recursive short-circuited version, see Another answer.
template<typename T, typename... Args> bool AreEqual(T first, Args... args) { return std::min({first==args...}); }
Finally, this version is attractive in its flaw:
template<typename T, typename... Args> bool AreEqual(T first, Args... args) { for(auto i : {args...}) if(first != i) return false; return true; }