如何知道编译器使用的隐式转换?

Cad*_*hon 6 c++ gcc implicit-conversion c++17

在一个大项目中,我有这段代码,编译得很好,但我不明白为什么。

std::vector<std::string> foo;
if(foo == 1) // Here is the error, the good code is "if(foo.size() == 1)"
  do_something();
Run Code Online (Sandbox Code Playgroud)

在一个简单的测试 main 中,它无法编译。我想编译器在某处找到一个运算符并将其用于隐式转换。

有没有办法知道使用的是哪一个?

我使用带有警告选项的 gcc 8.5.0 -Wall -Wextra -Wconversion

为了了解哪种代码会导致这种行为,下面是具有此类隐式转换的代码示例:

# 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;
}
Run Code Online (Sandbox Code Playgroud)

Cad*_*hon 5

回答我自己的问题

\n

为了找到隐式转换的来源,我创建了另一个隐式转换的来源。然后,编译器无法选择并显示可能性。

\n

例子:

\n
# include <string>\n# include <vector>\n# include <iostream>\n\nclass A\n{\n    public:\n        A() = default;\n        A(A const&) = default;\n        A(std::vector<std::string> const&) {}\n        A(int) {}\n};\nbool operator==(A const&, A const&) { return true; }\n\nclass B\n{\n    public:\n        B() = default;\n        B(B const&) = default;\n        B(std::vector<std::string> const& x) {}\n        B(int x) {}\n};\nbool operator==(B const&, B const&) { return false; }\n\nint main()\n{\n    std::vector<std::string> foo;\n    if(foo == 1)\n        std::cout << "foo == 1" << std::endl;\n    return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

海湾合作委员会输出:

\n
test_vector.cpp: In function \xe2\x80\x98int main()\xe2\x80\x99:\ntest_vector.cpp:28:9: error: ambiguous overload for \xe2\x80\x98operator==\xe2\x80\x99 (operand types are \xe2\x80\x98std::vector<std::__cxx11::basic_string<char> >\xe2\x80\x99 and \xe2\x80\x98int\xe2\x80\x99)\n  if(foo == 1)\n     ~~~~^~~~\ntest_vector.cpp:13:6: note: candidate: \xe2\x80\x98bool operator==(const A&, const A&)\xe2\x80\x99\n bool operator==(A const&, A const&) { return true; }\n      ^~~~~~~~\ntest_vector.cpp:23:6: note: candidate: \xe2\x80\x98bool operator==(const B&, const B&)\xe2\x80\x99\n bool operator==(B const&, B const&) { return false; }\n      ^~~~~~~~\n
Run Code Online (Sandbox Code Playgroud)\n

  • 正如未来读者的脚注:我们这里缺少构造函数的“显式”,因此编译器将混杂地隐式转换参数。不幸的是,“显式”是显式选择加入,而不是必须选择退出的默认设置。用 Kate Gregory 的话说,**所有默认设置都是错误的**。 (2认同)