I have an error I don't understand. The following snippet compiles
#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;
}
but the following doesn't not compile for index=0 when I overload the operator[](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;
}
and in this case I have the following compile-error:
main.cpp: In function 'int main()': main.cpp:25:8: error: ambiguous overload for 'operator[]' (operand types are 'Foo' and 'int') 25 | foo[0]; //doesn't compile main.cpp:12:5: note: candidate: 'Foo Foo::operator[](int) const' 12 | Foo operator[](int index) const {std::cout<<"size_t const\n"; return Foo{m_name};} main.cpp:13:5: note: candidate: 'Foo Foo::operator[](const std::string&) const' 13 | Foo operator[](std::string const& name) const { std::cout<<"str const\n"; return Foo{name}; } main.cpp:14:5: note: candidate: 'Foo Foo::operator[](const std::string&)' 14 | Foo operator[](std::string const& name) { std::cout<<"str non const\n"; return Foo{name}; } //doesn't compile with
- Why adding an overload with a
std::string
parameter make thefoo[0]
ambiguous ? - And why the problem is only with the index 0 ?
::std::string
constructors are implicit and a a general language defect allowing0
literal to be treated as a null pointer constant. So0
can be implicitly converted into string . @MarekR add -Wpedantic to enforce standard conformance – Skimmer0
is a special value, which can be converted to any pointer. So it can be treated asconst char*
which is implicitly convertible to std::string. Using+0
will trick compiler to assume type isint
(MSVC tdo not respect that): godbolt.org/z/PW3Eoj57e – Homocyclic