For std::pair
, I am just curious to know why this works
std::pair<int, int> response = {1, 2}
while, this doesn't:
if (response == {1, 2}) do something;
Is it because the operator =
is overloaded for std::pair while ==
isn't?
For std::pair
, I am just curious to know why this works
std::pair<int, int> response = {1, 2}
while, this doesn't:
if (response == {1, 2}) do something;
Is it because the operator =
is overloaded for std::pair while ==
isn't?
People have already provided the answer. I would just want to add.
EDIT: The second one is not a comparison with an std::initializer_list
and is invalid syntax actually since something like {1,2}
doesn't have any inherent type as such (try decltype({1,2}) x
. That's the language's syntax for list-initialization
which fails since this isn't a statement for initialization per se unlike x{1,2}
/x = {1,2}
/foo({1,2})
etc. Something like {1,2}
can be used to construct an initializer_list
using list-initialization
but isn't an std::initializer_list
in itself.
Comaprison operators between an std::pair
and an std::initializer_list
are not available and probably for a good reason because an initializr_list
is a
lightweight proxy object that provides access to an array of objects of type const T.
Note that the type of all the members of an initializer_list
is of the same type const T
. This isn't the case for a pair
that usually has distinct types T
and U
.
If you want, you could write an equality function between a pair
and an initializer_list
something as follows, obviously adhering to many constraints:
#include <iostream>
#include <type_traits>
#include <utility>
#include <initializer_list>
template <typename T, typename U>
bool foo(const std::pair<T, U>&pair,
const std::initializer_list<std::common_type_t<T, U>>& list) {
if(list.size() != 2) {
return false;
}
auto it = begin(list);
return pair.first == *it && pair.second == *std::next(it);
}
int main() {
{
std::pair<int, int> pair {1, 3};
std::initializer_list<int> list {1, 2};
std::cout<<std::boolalpha<<foo(pair, list)<<'\n';
}
{
std::pair<int, int> pair {1, 2};
std::initializer_list<int> list {1, 2};
std::cout<<std::boolalpha<<foo(pair, list)<<'\n';
}
{
std::pair<int, int> pair {1, 2};
std::initializer_list<int> list {1, 2, 3};
std::cout<<std::boolalpha<<foo(pair, list)<<'\n';
}
{
std::pair<int, char> pair {1, 2}; //common type is int
std::initializer_list<int> list {1, 2};
std::cout<<std::boolalpha<<foo(pair, list)<<'\n';
}
{
// std::pair<int, long> pair {1, 2}; //common type is long int
// std::initializer_list<int> list {1, 2}; //fails template substitution
// std::cout<<std::boolalpha<<foo(pair, list)<<'\n';
}
{
std::pair<int, long> pair {1, 2}; //common type is long int
std::initializer_list<long int> list {1, 2}; //same as common type of pair
std::cout<<std::boolalpha<<foo(pair, list)<<'\n';
}
{
std::pair<int, long> pair {1, 2}; //common type is long int
if(foo(pair, {1, 2})) {
std::cout<<"Matched\n";
}
}
}
This is just syntax: braced-init-list can be an operand only to
[]
and()
(on the inside) and=
and any@=
(on the right). The initialization case is also allowed, where there is no operator at all.