Search code examples
c++gccc++17implicit-conversion

How can I know the implicit conversion used by the compiler?


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;
}

Solution

  • 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; }
          ^~~~~~~~