错误:“operator[]”的重载不明确

alb*_*tor 5 c++ string operator-overloading

我有一个错误我不明白。以下代码片段编译

#include <iostream>

class Foo
{
    std::string m_name;

public:

    explicit Foo(std::string const& name):m_name{name}{}

    Foo operator[](int index) const {std::cout<<"size_t const\n"; return Foo{m_name};}
    Foo operator[](std::string const& name) const { std::cout<<"str const\n"; return Foo{name}; }
};

int main()
{
    Foo foo{"Cool"};
        
    foo[0]; 
    foo[1]; 
    
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

但当我重载时,以下内容不会编译为index=0operator[](std::string const&)

#include <iostream>

class Foo
{
    std::string m_name;

public:

    explicit Foo(std::string const& name):m_name{name}{}

    Foo operator[](int index) const {std::cout<<"size_t const\n"; return Foo{m_name};}
    Foo operator[](std::string const& name) const { std::cout<<"str const\n"; return Foo{name}; }
    Foo operator[](std::string const& name) { std::cout<<"str non const\n";  return Foo{name}; } //doesn't compile with
};

int main()
{
    Foo foo{"Cool"};
        
    foo[0]; //doesn't compile
    foo[1]; //compile
    
    
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我有以下编译错误:

#include <iostream>

class Foo
{
    std::string m_name;

public:

    explicit Foo(std::string const& name):m_name{name}{}

    Foo operator[](int index) const {std::cout<<"size_t const\n"; return Foo{m_name};}
    Foo operator[](std::string const& name) const { std::cout<<"str const\n"; return Foo{name}; }
};

int main()
{
    Foo foo{"Cool"};
        
    foo[0]; 
    foo[1]; 
    
    return 0;
}
Run Code Online (Sandbox Code Playgroud)
  1. 为什么添加带有参数的重载std::string会导致foo[0]歧义?
  2. 为什么问题只出在索引 0 上?

use*_*570 6

问题是构造函数不是显式的(并且是空指针常量) 这意味着重载和都是可行的,但具有相同的等级。这反过来意味着该调用是不明确的,因为它们都不比另一个更好。std::string::string(const char*)0Foo::Foo operator[](int) constFoo::Foo operator[](const std::string&)

特别是,Foo::Foo operator[](int) const需要转换其第一个隐式参数,但不需要转换其第二个int参数。另一方面,Foo::Foo operator[](const std::string&)不需要对其第一个隐式参数进行转换,但需要使用构造函数从到进行隐式转换。由于这些重载都不比另一个更好,因此调用是不明确的。0std::stringstd::string::string(const char*)


请注意,此问题不会发生在重载之间Foo::Foo operator[](int) constFoo::Foo operator[](const std::string&) const因为在这种情况下,前者比后者更匹配,因为它不需要对其第二个int参数进行任何转换,并且这两个重载都需要对其第一个隐式参数进行转换。


因此,一个简单(直接)的修复方法是添加一个非常量重载Foo::Foo operator[](int index)