And now some practical C++17 applications. No SFINAE necessary.
//----------------------------------
// constexpr lambda requires C++17
auto eq3 = [] (auto v1, auto v2, auto v3) constexpr -> bool
{
return ( v1 == v2 ) && ( v2 == v3 );
};
Usage is simple but fully compile time
constexpr auto same_ = eq3(42,42,42);
std::bool_constant< eq3(42,42,42) > twins_ ;
For comparing a whole sequences of values, concept is the same, impementation is a little bit more involved.
template<typename ... T>
constexpr bool all_equal ( const T & ... args_ )
{
if ((sizeof...( args_) ) < 2) return true;
// for non recursive version
const auto il_ = { args_ ... };
// compare them all to the first
auto first_ = *(il_.begin()) ;
// assumption
bool rezult_{ true };
for ( auto && elem_ : il_) {
// yes I know, first cycle compares first_ to itself ...
rezult_ = rezult_ && ( first_ == elem_ );
// short circuit-ing
if (!rezult_) break;
}
return rezult_;
};
"just" a function, compile time, again no variadic template trickery.
bool_constant< all_equal(42,42,42,42,42,42,42) > same_ ;
cout << endl << boolalpha << same_() ;
bool_constant< all_equal(42,43,44,45,46,47) > not_same_ ;
cout << endl << boolalpha << not_same_() ;
Mandatory Wandbox is here.
ps: somewhat predictable all_equal
does not compile using the very latest CL also known as MSVC or Visual Studio.