In a big project, I have this code, compiling well, but I don't understand why.
std::vector<std::string> foo;
if(foo == 1) // Here is the error, the good code is "if(foo.size() == 1)"
do_something();
In a simple test main, it doesn't compile. I suppose the compiler finds an operator somewhere and uses it with implicit conversion.
Is there a way to know which one is used ?
I use gcc 8.5.0 with warning options -Wall -Wextra -Wconversion
.
In order to understand which kind of code can induce this beheviour, here is an example of a code having such an implicit conversion:
# include <string>
# include <vector>
# include <iostream>
class A
{
public:
A() = default;
A(A const&) = default;
A(std::vector<std::string> const&) {}
A(int) {}
};
bool operator==(A const&, A const&) { return true; }
int main()
{
std::vector<std::string> foo;
if(foo == 1)
std::cout << "foo == 1" << std::endl;
return 0;
}
Answering my own question
In order to find the source of the implicit conversion, I created another source of implicit conversion. Then, the compiler can't choose and shows the possibilities.
Example:
# include <string>
# include <vector>
# include <iostream>
class A
{
public:
A() = default;
A(A const&) = default;
A(std::vector<std::string> const&) {}
A(int) {}
};
bool operator==(A const&, A const&) { return true; }
class B
{
public:
B() = default;
B(B const&) = default;
B(std::vector<std::string> const& x) {}
B(int x) {}
};
bool operator==(B const&, B const&) { return false; }
int main()
{
std::vector<std::string> foo;
if(foo == 1)
std::cout << "foo == 1" << std::endl;
return 0;
}
GCC output:
test_vector.cpp: In function ‘int main()’:
test_vector.cpp:28:9: error: ambiguous overload for ‘operator==’ (operand types are ‘std::vector<std::__cxx11::basic_string<char> >’ and ‘int’)
if(foo == 1)
~~~~^~~~
test_vector.cpp:13:6: note: candidate: ‘bool operator==(const A&, const A&)’
bool operator==(A const&, A const&) { return true; }
^~~~~~~~
test_vector.cpp:23:6: note: candidate: ‘bool operator==(const B&, const B&)’
bool operator==(B const&, B const&) { return false; }
^~~~~~~~