Why isn't it possible to compare two tuples of different size like this:
#include <tuple>
int main() {
std::tuple<int, int> t1(1, 2);
std::tuple<int> t2(1);
if(std::tuple_size<decltype(t1)>::value == std::tuple_size<decltype(t2)>::value)
return (t1 == t2);
else
return 0;
}
I know that t1==t2
is not possible. But in this example it wouldn't be executed. Is there a possibility to compare tuples of different sizes?
operator==
requires the tuples to be of equal lengths.
§ 20.4.2.7 [tuple.rel]:
template<class... TTypes, class... UTypes> constexpr bool operator==(const tuple<TTypes...>& t, const tuple<UTypes...>& u);
1 Requires: For all
i
, where0 <= i
andi < sizeof...(TTypes)
,get<i>(t) == get<i>(u)
is a valid expression returning a type that is convertible tobool
.sizeof...(TTypes) == sizeof...(UTypes)
.
If you want two tuples of different lengths to be considered unequal, you'd need to implement this logic yourself:
template <typename... Ts, typename... Us>
auto compare(const std::tuple<Ts...>& t1, const std::tuple<Us...>& t2)
-> typename std::enable_if<sizeof...(Ts) == sizeof...(Us), bool>::type
{
return t1 == t2;
}
template <typename... Ts, typename... Us>
auto compare(const std::tuple<Ts...>& t1, const std::tuple<Us...>& t2)
-> typename std::enable_if<sizeof...(Ts) != sizeof...(Us), bool>::type
{
return false;
}
DEMO
This way, the code comparing two tuples, t1 == t2
, is instantiated only when the lengths of tuples match each other. In your scenario, a compiler is unable to compile your code, since there is no predefined operator==
for such a case.
You may write several overloads:
template<typename ...Ts>
bool is_equal(const std::tuple<Ts...>& lhs, const std::tuple<Ts...>& rhs)
{
return lhs == rhs;
}
template<typename ...Ts, typename... Us>
bool is_equal(const std::tuple<Ts...>&, const std::tuple<Us...>&)
{
return false;
}
Live example
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With